BackgroundWorker DisconnectedContext

时间:2012-07-15 18:10:32

标签: c# wpf backgroundworker

我有以下代码:

public static Emgu.CV.Capture _capture;
public static DispatcherTimer _timer;
_timer = new DispatcherTimer();
_timer.Interval = _settings.camera_interval;
_timer.Tick += ProcessFrame;
BacgroundWorker _bw = new BackgroundWorker
{
    WorkerReportsProgress = true,
    WorkerSupportsCancellation = true
};

_bw.DoWork += (s, e) =>
{
    // Initialize the device in background
    _capture = new Capture();
};

_bw.RunWorkerCompleted += (s, e) =>
{
    _capture.SetCaptureProperty(CAP_PROP.CV_CAP_PROP_FRAME_HEIGHT,
        _settings.camera_height);
    _capture.SetCaptureProperty(CAP_PROP.CV_CAP_PROP_FRAME_WIDTH,
        _settings.camera_width);
    Brightness = _capture
        .GetCaptureProperty(CAP_PROP.CV_CAP_PROP_BRIGHTNESS);

    Contrast = _capture
        .GetCaptureProperty(CAP_PROP.CV_CAP_PROP_CONTRAST);

    // Get images from camera
    _timer.Start();
};

_bw.RunWorkerAsync();
 public override void CleanUp()
 {
     _timer.Stop();            
     _bw.Dispose();
     if (_capture != null) _capture.Dispose();
 }

应用程序运行正常,但当我关闭应用程序时抛出我:Message: Context0x23754b0' Disconnected. ... 如何解决此问题?

2 个答案:

答案 0 :(得分:1)

我认为这与您的相机捕获库有关,以及它如何使用非托管资源。

我首先评论您的RunWorkerCompleted中的所有代码,看看该消息是否仍然存在。如果没有,那么它是由一个或多个GetCaptureProperty调用引起的。我怀疑它不会。

我在Egmu.CV.Capture的documentation中看到有一个Capture.DisposeObject()方法讨论释放捕获的对象。我的猜测是,在您实例化_capture并执行您需要执行的操作后,您必须进行清理。我建议您在ProcessFrame完成后(或在退出申请时)尝试拨打_capture.DisposeObject()以查看是否可以清理并正常退出。

修改

如果所有其他方法都失败了,我建议的方法就是尽可能多地注释掉你的代码,以便在没有抛出异常的情况下退出程序。然后,对代码的某些部分进行注释,直到您可以准确找到创建或运行的内容,最终会导致退出时出现异常。一旦你可以对其进行本地化,你就会更好地了解如何修复它。

答案 1 :(得分:1)

这是一个与COM相关的错误,毫无疑问会发生,因为您在后台线程上创建了Capture对象。 COM对象具有线程关联性,一旦创建它的线程停止运行,COM对象就会死亡,不能再使用了。无论如何都试图使用它会产生警告。

在RunWorkerCompleted事件处理程序中不会发生这种情况非常了不起,这必须以非显而易见的方式隐藏在OpenCV或Emgu管道中。这当然并不意味着它有一天不会发生。您需要重新考虑这一点,仅在worker上创建对象并在UI线程上运行其他所有内容没有多大意义。做好工人的一切,包括处理。或者都不是。