2012-07-15 62 views
0

我有folling代码:BackgroundWorker的DisconnectedContext

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

回答

1

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

我会先评论RunWorkerCompleted以外的所有代码,看看这个消息是否仍然发生。如果没有,那么它是由一个或多个GetCaptureProperty调用引起的。我怀疑它不会。

我在Egmu.CV.Capture的documentation中看到有一个Capture.DisposeObject()方法说明释放捕获的对象。我的猜测是,当你实例化_capture并且你做了你需要做的事情之后,你必须做一个清理。我建议您在ProcessFrame完成(或退出应用程序)后,尝试拨打_capture.DisposeObject()以查看是否清理并退出正常。

编辑:

如果一切都失败了,我会建议的方法是注释掉尽可能多你的代码,你可以去那里你可以退出程序没有它抛出一个异常点。然后,在部分代码中进行注释,直到您可以准确找到创建或运行的内容,这些内容最终会导致出现异常。一旦你可以本地化,你会有更好的想法如何解决它。

+0

我忘了清理方法。我会写 – rkmax 2012-07-15 18:51:45

+0

@rkmax,就像一个很好的做法,我会按照与创建相反的顺序处理Dispose,然后尝试显式的Capture.DisposeObject()方法。哦,我会从这些字段中删除'static'修饰符......实际上可能是问题所在。 – 2012-07-15 19:01:54

+0

我试过静态和无静态 – rkmax 2012-07-15 19:04:03

1

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

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