我在.net 3.5上使用C#(不能使用更高版本)
我有一个阻塞队列的实现,它基于http://element533.blogspot.com/2010/01/stoppable-blocking-queue-for-net.html松散地实现了Producer-Consumer模式
我在同一命名空间中有4个文件:
代码的重要部分
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()
答案 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 无法通过您创建的所有对象,您将会有闲置的对象。在生产者/消费者模型中,消费者有责任照顾所生产的产品。