1

我有这个缓冲算法

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 是一个布尔值,当图像数据被写入 ArrayAnsammlung 时为真。
  • Nummerierung 是一个帮助分离图像的计数器

它可以工作,但根据分析器,它的负载很高

while (aufnahme || ArrayAnsammlung.Count - 1 > 0)

它使应用程序延迟运行。

我怎样才能优化这个,或者特别是使用 Parallel.For 而不弄乱顺序。因此,在并行执行时,顺序必须与 for 循环中的相同。

PS:我加了

Thread.Sleep(60);

这对减轻工作量有帮助吗?

4

2 回答 2

3

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

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

但更好和更简单的解决方案是使用ConcurrenQueue<T>or a BlockingCollectionhere。然后,您可以使用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在周围循环使用了。

于 2013-01-17T19:35:35.420 回答
0

你为什么不尝试:

Thread.Sleep(0);

来自MSDN:“指定零 (0) 以指示该线程应暂停以允许其他等待线程执行。”

于 2013-01-17T19:35:56.540 回答