0

我有以下代码:

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. ... 如何解决这个问题?

4

2 回答 2

2

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

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

于 2012-07-15T20:50:34.357 回答
1

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

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

我在 Egmu.CV.Capture 的文档中看到有一种Capture.DisposeObject()方法可以谈论释放捕获的对象。我的猜测是,在您实例化_capture并完成您需要做的事情之后,您必须进行清理。我建议在您ProcessFrame完成后(或在您的应用程序退出时)尝试调用_capture.DisposeObject()以查看是否清理并正常退出。

编辑:

如果一切都失败了,我建议的方法是尽可能多地注释掉你的代码,以达到可以退出程序而不抛出异常的程度。然后,在部分代码中进行注释,直到您可以准确找到创建或运行的内容,最终导致退出时出现异常。一旦你可以本地化它,你就会更好地了解如何修复它。

于 2012-07-15T18:48:34.290 回答