C#:如何防止调用失败

标签 c# winforms multithreading event-handling

我有一个 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/

相关文章:

c# - 尝试声明 Func<void> 时,不能在此上下文中使用关键字 'void'

Winforms ClickOnce 发布因 app.config 转换而失败

c# - 在生成的邮件中添加默认的outlook签名

c++ - 如何在c linux中通过服务器处理多个套接字客户端

c# - 在c#中将消息从子任务传递到父任务

c# - 从文件服务器调试神秘消失的文件

c# - 如何创建包含所有其他内容的 dll?

c# - 在DataGrid中选择多个单元格并输出到Excel工作表

c# - “如果”语句

ios - EXIF 的 PHContentEditingInputRequestOptions block 主线程