C#[.NET 3.5]多线程和位图-不同/不一致的错误
我正在使用.NET3.5上的C#(无法使用更高版本) 我有一个阻塞队列的实现,它松散地基于 我在同一命名空间中有4个文件:C#[.NET 3.5]多线程和位图-不同/不一致的错误,c#,.net,multithreading,image-processing,bitmap,C#,.net,Multithreading,Image Processing,Bitmap,我正在使用.NET3.5上的C#(无法使用更高版本) 我有一个阻塞队列的实现,它松散地基于 我在同一命名空间中有4个文件: 文件0包含主函数,并为func1启动两个线程 和func2,并实例化上述队列的一个对象 File1具有func1,它将视频分割为单独的图像帧(位图),并将其排入上述队列。如果添加了所有项目,则会 表示已完成添加到队列。担任制作人 File2有一个func2,它检查队列中是否有可用的项,然后将第一个元素出列。充当消费者 包含队列的实现 重要的代码位 职能1 无论何时运行,fu
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);
}
}
尝试删除
oneFrame.Dispose()代码>来自func1。它在排队后立即被标记为处置。它看起来像是func2正在使用一次性对象,并且当它退出使用
块时,仍将尝试处置它
编辑:需要记住的一件事是,如果func2无法通过您创建的所有对象,您将有未经散点的对象挂起。在生产者/消费者模型中,消费者有责任处理所生产的内容。@user3243571-参见我编辑的代码-基本上是从dequeud帧的图像构造位图。不,这也不起作用。我感觉问题可能出在oneFrame.Dispose()中func1@user3243571我刚刚注意到-您正在使用一个阻塞队列,它可能在while语句中被阻塞,请在每次迭代中重新分配变量:bool IsComplete=false;虽然(!(IsComplete=ImageProcessor.frameQueue.isCompleted())我做了同样的事情,但它仍然有效。然而,当它必须处理大量的帧时,这似乎会在以后的过程中引起问题。本质上,func2()包含的不仅仅是打印高度和宽度,因此处理每个位图需要一段时间,而func1()的速度非常快。您没有任何限制项目上限的内容。您可以考虑在将函数添加到函数(函数)中的队列之后检查队列大小,并强制它等待直到低于最大值。YEP,这正是我在观察到这种行为后决定要做的。谢谢虽然我已经让消费者等待生产商在队列中放置项目。现在我需要让生产者等待消费者从队列中删除项目。我来了!只要保证当func1()发出信号时,在func2()中isCompleted()将返回true,就应该没有问题。如果isCompleted()即使在完成后仍继续返回false,func2()将永远等待。oneFrame.Dispose()完全错误,您必须删除它。如果这是针对Windows的,并且位图具有窗口句柄(因此它们是基于GDI的,具有设备上下文而不仅仅是内存映射),则您不能在WindProc主线程之外使用它们。如果您这样做,将使WinAPI无效(就像主线程之外的任何其他可视组件调用一样),通常一开始不会发生任何错误,但过了一段时间,您会遇到随机访问冲突,并在不相关的WinAPI或GDI调用上崩溃。有时需要几分钟,有时只需要几秒钟…(最后一次测试是在Win XP上进行的,因此新版本的表现可能会有所不同)
An unhandled exception of type 'System.NullReferenceException' occurred
Additional information: Object reference not set to an instance of an object.
An unhandled exception of type 'System.ArgumentException' occurred in System.Drawing.dll
Additional information: Parameter is not valid.
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);
}
}