为并行执行优化缓冲样本

本文关键字:样本 缓冲 优化 并行执行 | 更新日期: 2023-09-27 17:54:29

我有这个缓冲算法

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是一个数组,包含每个字段的图像数据。所以部分的遍历字节数组的内容。
  • 这一切都发生在一个线程中,而在另一个线程中,图像正在被写入ArrayAnsammlung。缓冲区是必要的,因为传输的图像比处理的图像多(转换为jpeg)。
  • aufnahme是一个bool值,当图像数据写入ArrayAnsammlung时为true。
  • Nummerierung是一个计数器,帮助分离图像

它可以工作,但是根据分析器它在

周围有高负载
while (aufnahme || ArrayAnsammlung.Count - 1 > 0)

,它使应用程序表现为延迟。

我如何优化这个,特别是使用并行。在不打乱顺序的情况下。因此,当并行执行时,顺序必须与for循环中的顺序相同。

PS:我添加了

Thread.Sleep(60);

这有助于减少工作量吗?

为并行执行优化缓冲样本

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

你为什么不试试:

Thread.Sleep(0);

来自MSDN: "指定零(0)表示该线程应该挂起以允许其他等待线程执行。"