1

我是 c# 和并行处理的新手。我正在尝试处理一堆图像,我已经编写了处理方法。我在 imagelist 上添加了并行 foreach 循环,如下所示

    Parallel.ForEach(Directory.GetFiles(path), new ParallelOptions { MaxDegreeOfParallelism = 2 }, fileName =>
            {
                List<string> tempList = new List<string>();
                using (Bitmap imageBitmap= new Bitmap(fileName))
                {
                    using (ImageProcessor imageProcessor= new ImageProcessor ())
                    {
                        tempList = imageProcessor.ProcessImage(imageBitmap);
                    }
                }
                if (tempList.Count != 0)
                    allElements.Add(tempList.FirstOrDefault());
            });

在其中一种方法中,我使用该LockBits方法获取BitMapData图像并将该数据复制到byte[]但是方法抛出异常,方法代码是

   private byte[] ImageToByteArray(Bitmap b, out int stride)
    {
        object sync = new object();
        BitmapData bd;
        lock (sync)
        {
            Rectangle rect = new Rectangle(0, 0, b.Width, b.Height);
            bd = b.LockBits(rect, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);//This line throwing the exception.

            try
            {
                byte[] pxl = new byte[bd.Stride * b.Height];
                Marshal.Copy(bd.Scan0, pxl, 0, bd.Stride * b.Height);
                stride = bd.Stride;
                return pxl;
            }
            finally
            {
                b.UnlockBits(bd);
            }
        }
    }

我尝试lock了使用该LockBits方法的代码,因此一次只有一个线程使用该代码,因此一次使用内存。

我还尝试使用lock父方法中的方法的 with 调用,例如

    public List<string> ProcessImage(BitMap image)
    {
        object sync = new object();
        int stride;
        byte[] rawImg;
        using (image)
        {
            lock (sync)
            {
                rawImg = ImageToByteArray(image, out stride);
            }
            processingImg = new ProcessImage(rawImg, image.Width, image.Height);
        }
  }

但仍然有例外。异常没有给我任何堆栈跟踪或解释,只有我得到的异常消息是Out Of Memory

我遇到了这个答案,当我减少它时MaximumDegreeOfParallelism它工作正常。

所以基本上我想知道,1)为什么即使代码上Out Of Memory有2个线程,代码也会抛出异常lock?2)如果我增加,是否有可能避免这个异常DegreeOfParallelism?任何帮助都会很棒。


如有任何混淆,请随时发表评论。

4

1 回答 1

0
  1. 问题是您要处理的图像有多大。也许它们太大了。我的经验还表明,调用LockBits 会分配额外的内存量——实际上它会使分配的内存量翻倍。您是否尝试处理一些非常小的图片?

  2. 代码中的没有任何作用,因为您锁定的是局部变量。如果您想在线程之间同步对临界区的访问并且您想使用来实现,那么您必须使用一个在所有这些线程之间共享的对象。在您的情况下,同步对象应声明为ImageProcessor类的私有字段。

  3. 我认为增加DegreeOfParallelism将无济于事,甚至会使事情变得更糟,因为您的代码将需要更多内存来处理更多图像。

于 2014-07-22T08:52:44.533 回答