C#[.NET 3.5]多线程和位图 - 不同/不一致的错误

时间:2015-09-25 17:59:52

标签: c# .net multithreading image-processing bitmap

我在.net 3.5上使用C#(不能使用更高版本)

我有一个阻塞队列的实现,它基于http://element533.blogspot.com/2010/01/stoppable-blocking-queue-for-net.html松散地实现了Producer-Consumer模式

我在同一命名空间中有4个文件:

  1. File0包含main函数并为func1启动两个线程 和func2并实例化上述队列的对象
  2. File1具有func1,可将视频分割为单个图像帧(位图),并将它们排入上述队列。如果添加了所有项目,则为 表示已完成添加到队列的信号。充当制片人
  3. File2有func2,用于检查队列中是否有可用的项目,然后将第一个元素出列。充当消费者
  4. 包含队列的实现
  5. 代码的重要部分

    func1的

            for (int index = 0; index < numFrames; index++)
            {
                Bitmap oneFrame = videoReader.ReadVideoFrame();
                ImageProcessor.frameQueue.Enqueue(oneFrame);
                oneFrame.Dispose();
            }
    

    FUNC2

    while (!ImageProcessor.frameQueue.isCompleted())
                {             
                    using (Bitmap image = ImageProcessor.frameQueue.Dequeue())
                    {
                        Console.WriteLine("Height: " + image.Height);
                        Console.WriteLine("Width: " + image.Width);                    
                    }                
                }
    

    每当运行时,func1按预期运行,但func2在尝试访问image.Height时会抛出不同类型的错误。我看到的一些错误是

    1)

    An unhandled exception of type 'System.InvalidOperationException' occurred in System.Drawing.dll
    Additional information: Object is currently in use elsewhere.
    

    2)

    An unhandled exception of type 'System.NullReferenceException' occurred 
    Additional information: Object reference not set to an instance of an object.
    

    3)

    An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll
    Additional information: Parameter is not valid.
    

    任何猜测我做错了什么?我可以不在位图中使用多线程吗?

    我觉得问题可能出在func1中的oneFrame.Dispose()

2 个答案:

答案 0 :(得分:0)

只是预感:

尝试将其置于使用声明之外: 而不是:

        using (Bitmap image = ImageProcessor.frameQueue.Dequeue())
        {

            Console.WriteLine("Height: " + image.Height);
            Console.WriteLine("Width: " + image.Width);                    
        }  

试试这个:

            Bitmap image = new Bitmap((System.Drawing.Image)ImageProcessor.frameQueue.Dequeue());             
                Console.WriteLine("Height: " + image.Height);
                Console.WriteLine("Width: " + image.Width);                    
            image.Dispose();

修改

bool IsComplete = false;
while (!(IsComplete = ImageProcessor.frameQueue.isCompleted())) 
            {             
                using (Bitmap image = ImageProcessor.frameQueue.Dequeue())
                {
                    Console.WriteLine("Height: " + image.Height);
                    Console.WriteLine("Width: " + image.Width);                    
                }                
            }

答案 1 :(得分:0)

尝试从 func1 中删除oneFrame.Dispose();。排队后正在标记处理。看起来 func2 正在消耗一次性对象,并且当它退出using块时会尝试处理它。

编辑:要记住的一件事是,如果 func2 无法通过您创建的所有对象,您将会有闲置的对象。在生产者/消费者模型中,消费者有责任照顾所生产的产品。