c#(.多线程和位图-不同/不一致的错误
本文关键字:不一致 错误 不同 多线程 位图 | 更新日期: 2023-09-27 18:14:30
我在。net 3.5上使用c#(不能使用更高版本)
我有一个阻塞队列的实现,它实现了基于http://element533.blogspot.com/2010/01/stoppable-blocking-queue-for-net.html的生产者-消费者模式。
我有4个文件在同一个命名空间:
- File0包含main函数并为func1启动两个线程和func2并实例化上述队列 的对象。
- File1有func1,它将视频分成单独的图像帧(位图),并将它们排队到上述队列。如果添加了所有项,则为表示它已完成向队列添加。作为生产者
- File2有func2,检查队列中是否有可用的项目,然后将第一个元素从队列中取出。作为消费者
- 包含队列 的实现。
重要的代码位
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
尝试从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);
}
}