0

我已经使用 BlockingCollection 实现了生产者/消费者模式,但它似乎并没有像我预期的那样阻塞。

我有一个线程从网络摄像头接收帧并将它们添加到 BlockingCollection

private void video_NewFrame(object sender, NewFrameEventArgs eventArgs) {
    image = (Bitmap)eventArgs.Frame.Clone();
    queue.Add(image);
    if (NewFrame != null)
        NewFrame(this, new NewFrameEventArgs(image)); //invoke the event for display
}

在另一个线程中,我引用了集合并使用处理框架

public void Run() {
    foreach (Bitmap bmp in queue.GetConsumingEnumerable()) {
        // process bitmap

但是,正如您在下面看到的,它往往会抛出一个 InvalidOperationException 告诉我我正在拉的 Frame 正在其他地方使用。

img http://i17.photobucket.com/albums/b52/orubap/2012-03-24_020858.png

它并不总是立即发生,但我注意到它仅在队列为空或接近空时发生(即消费者比生产者快)所以我猜这与添加的第一个图像或拍摄的最后一张照片。任何想法为什么会发生这种情况?

4

1 回答 1

0

video_NewFrame当图像传递给NewFrame事件处理程序时,执行的线程正在使用图像。由于它与 并发运行Run,因此没有什么可以阻止两个线程image同时访问。(这只会在事件处理程序处理Run图像时将图像出列时NewFrame发生,这解释了为什么只有在队列为空或几乎为空时才能看到它。)

一种解决方法可能是将调用移至NewFrame 之前 queue.Add(image);(in video_NewFrame)。这将确保Run在事件处理程序完成之前看不到它(假设事件处理程序不存储对它的引用)。

于 2012-03-24T03:30:40.137 回答