首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >LockBits()并行抛出内存?

LockBits()并行抛出内存?
EN

Stack Overflow用户
提问于 2014-07-22 08:06:18
回答 1查看 820关注 0票数 1

全新的c#和并行处理。我正在尝试处理这些图像,我已经为processing.And编写了方法,我在imagelist上添加了并行的foreach循环,如下所示

代码语言:javascript
复制
    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[],但是方法抛出异常,方法的代码是

代码语言:javascript
复制
   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调用来自父方法的方法,如

代码语言:javascript
复制
    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

我偶然发现了this的答案,当我减少MaximumDegreeOfParallelism时,它正确地工作了。

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

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

EN

回答 1

Stack Overflow用户

发布于 2014-07-22 08:52:44

  1. 问题是你想要处理的图像有多大。也许它们太大了。我的经验还显示,调用LockBits会分配额外的内存量--有效地将分配的内存量增加一倍。你试过处理一些很小的图片吗?
  2. 代码中的锁不起任何作用,因为您正在锁定局部变量。如果您希望同步线程之间对关键部分的访问,并且希望使用锁进行访问,则必须使用在所有这些线程之间共享的对象。在您的示例中,同步对象应该声明为ImageProcessor类的私有字段。
  3. 我认为增加DegreeOfParallelism不会有帮助,甚至会使事情变得更糟,因为您的代码需要更多的内存来处理更多的图像。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24881950

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档