我有一个 UserControl,其中包含一些后台工作。当事物有完成事件时,用户控件将订阅该事件。由于事件是在单独的线程中引发的,并且事件处理程序对用户控件进行了一些更新,所以我用这个启动事件处理程序:
private void ProcessProcessCompleted(object sender, ProcessCompletedEventArgs e)
{
if (InvokeRequired)
{
Invoke(new Action<object, ProcessCompletedEventArgs>(ProcessProcessCompleted),
new[] { sender, e });
return;
}
// Update the user control, etc.
}
这工作正常,除非包含用户控件的表单在进程完成之前关闭。我试图在用户控件的 dispose 方法中取消订阅该事件,但这似乎只在部分时间有效。我应该怎么做?想避免将其包装在 try catch block 中。是否有 InvokeIsPossible
属性或我可以在调用之前检查的内容?
最佳答案
您可以使用 SynchronizationContext
,它是在 .NET 2 中引入的以简化线程间通信:
- 创建一个全局 SynchronizationContext 变量(假设是 syncContext)
将其初始化为表单的线程同步上下文:
syncContext = SynchronizationContext.Current;
像这样更改您的 ProcessProcessCompleted
方法:
private void ProcessProcessCompleted(object sender, object e)
{
this.syncContext.Post(new SendOrPostCallback(delegate(object state)
{
// Update the user control, etc.
})
, null);
}
您可以在此处阅读有关 SynchronizationContext
的信息:
http://www.codeproject.com/KB/cpp/SyncContextTutorial.aspx
或http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.aspx
关于C#:如何防止调用失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1390572/