c# - 优化缓冲样本以并行执行

标签 c# multithreading

我有这个缓冲算法

while (aufnahme || ArrayAnsammlung.Count > 1)
{
    if (ArrayAnsammlung != null)
    {
        int l = ArrayAnsammlung.Count - 1;
        //db(l.ToString());


        for (int DurchLaeufer = 0; DurchLaeufer < l; DurchLaeufer++)
        {
            if (ArrayAnsammlung[DurchLaeufer] != null)
            {
                Nummerierung = Convert.ToString(Nummerierungszaehler);
                Enkodierung = new JpegBitmapEncoder();
                Enkodierung.FlipHorizontal = true;
                //Enkodierung.FlipVertical = false;
                var dateiStrom = new FileStream("E:\\Temp\\" + datum + " " + Nummerierung.PadLeft(12, '0') + ".jpg", FileMode.Create);
                Enkodierung.Frames.Add(BitmapFrame.Create(BitmapSource.Create(bildbreite, bildhoehe * 2,
                96, 96, PixelFormats.Bgr32, null, ArrayAnsammlung[DurchLaeufer], stride)));
                Enkodierung.Save(dateiStrom);
                dateiStrom = null;
                Enkodierung = null;
                Nummerierungszaehler++;
            }
        }
        if (l > 0)
        {
            ArrayAnsammlung.RemoveRange(0, l);
        }
    }
    Thread.Sleep(60);
}
  • DurchLaeufer只是一个索引。
  • ArrayAnsammlung是一个在每个字段中包含图像数据的数组。因此,for部分将遍历字节数组的内容。
  • 这一切都发生在一个正在运行的线程中,而在另一个线程中,将镜像写入ArrayAnsammlung。该缓冲区是必需的,因为要传递的图像多于已处理的图像(转换为jpeg)。
  • aufnahme是 bool 值,当将图像数据写入ArrayAnsammlung时为true。
  • Nummerierung是可帮助分离图像的计数器

  • 它可以工作,但是根据分析器,它周围的负载很高
    while (aufnahme || ArrayAnsammlung.Count - 1 > 0)
    

    并导致应用延迟运行。

    我该如何优化它,或者特别是使用Parallel.For而不弄乱顺序。因此,在并行执行时,顺序必须与for循环中的顺序相同。

    PS:我加了
    Thread.Sleep(60);
    

    这有助于减轻工作量吗?

    最佳答案

    it has a high load around while (aufnahme || ArrayAnsammlung.Count - 1 > 0)



    这意味着当数组为空时它循环很多。您可以使用WaitHandle解决此问题,没有理由将CPU浪费在一个空集合上。

    但是更好,更简单的解决方案是在此处使用ConcurrenQueue<T>BlockingCollection。然后,您可以使用myQueue.Take()解决此特定问题。

    好的,请求的代码示例:
    //untested
    
    // the new definition
    private BlockingCollection<byte[]> ArrayAnsammlung = new BlockingCollection<byte[]>();
    
    
    while (aufnahme)
    {
       byte[] data = ArrayAnsammlung.Take();
    
       if (data != null)
       {
         int localNum = Interlocked.Increment(ref Nummerierung);  // initialize it 1 lower
    
          ... // process data
       }
    }
    

    这是一个粗略的想法。您可能要检查用CompleteAdding()停止的结果。

    附带问题:
    while (aufnahme || ArrayAnsammlung.Count - 1 > 0)
    {
        if (ArrayAnsammlung != null)
        {
    
    != null测试为时已晚,您已经在周围的循环中使用了.Count

    关于c# - 优化缓冲样本以并行执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14386638/

    相关文章:

    c# - 使用 WCF Web 服务时获取 System.ServiceModel.ProtocolException

    c# - 无效的 Continuation token CosmosDB

    c# - 跨 Sharepoint 服务器上所有站点和子站点的 Linq 查询?

    c# - 使用线程来加速进程

    c# - 为什么 Database.Query() 当空时返回 null?

    c# - 编译时禁用 Dll 文化文件夹

    cocoa - 异步网络+线程问题

    c++ - C++技术建议中多线程环境中暂停和恢复一个线程从另一个线程

    multithreading - Visual Studio : How to breakpoint at a yet-unknown location?

    ios - 2个后台进程队列