我有以下代码:
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. ...
如何解决此问题?
答案 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线程上运行其他所有内容没有多大意义。做好工人的一切,包括处理。或者都不是。