c#(.多线程和位图-不同/不一致的错误

本文关键字:不一致 错误 不同 多线程 位图 | 更新日期: 2023-09-27 18:14:30

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

我有一个阻塞队列的实现,它实现了基于http://element533.blogspot.com/2010/01/stoppable-blocking-queue-for-net.html的生产者-消费者模式。

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

  1. File0包含main函数并为func1启动两个线程和func2并实例化上述队列
  2. 的对象。
  3. File1有func1,它将视频分成单独的图像帧(位图),并将它们排队到上述队列。如果添加了所有项,则为表示它已完成向队列添加。作为生产者
  4. File2有func2,检查队列中是否有可用的项目,然后将第一个元素从队列中取出。作为消费者
  5. 包含队列
  6. 的实现。

重要的代码位

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

c#(.多线程和位图-不同/不一致的错误

中的oneFrame.Dispose()中。

尝试从func1中删除oneFrame.Dispose();。它被标记为在排队后立即处理。看起来func2正在使用可丢弃对象,并且在退出using块时将尝试丢弃它。

编辑:要记住的一件事是,如果func2不能通过您创建的所有对象工作,则将有未处理的对象挂在周围。在生产者/消费者模型中,消费者有责任照管生产出来的产品。

直觉:

试着把它放在using语句之外:而不是:

        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);                    
                }                
            }