c# - 如何将异常显式传递给 C# 中的主线程

标签 c# multithreading

我很熟悉在一个线程中抛出的异常通常无法在另一个线程中捕获的事实。 我如何将错误转移到主线程?

public static void Main()
{
   new Thread (Go).Start();
}

static void Go()
{
  try
  {
    // ...
    throw null;    // The NullReferenceException will get caught below
    // ...
  }
  catch (Exception ex)
  {
    // Typically log the exception, and/or signal another thread
    // that we've come unstuck
    // ...
  }
}

最佳答案

如果您使用的是 .NET 4,则可以通过 Tasks 实现更好的方法,但假设您需要使用 Threads...

如果您的示例是控制台应用程序,那么您的 Main 方法可能会在 Go 开始执行之前退出。所以抛出异常时你的“主线程”可能不存在。要停止这种情况,您需要一些同步。

应该这样做:

static Exception _ThreadException = null;

public static void Main()
{
    var t = new Thread ( Go );
    t.Start();

    // this blocks this thread until the worker thread completes
    t.Join();

    // now see if there was an exception
    if ( _ThreadException != null ) HandleException( _ThreadException );
}

static void HandleException( Exception ex )
{
    // this will be run on the main thread
}

static void Go()
{
    try
    {
        // ...
        throw null;    // The NullReferenceException will get caught below
        // ...
    }
    catch (Exception ex) 
    {
        _ThreadException = ex;
    }
}

如果这是一个 UI 应用程序,事情就会简单一些。您需要将一些对 UI 线程的引用传递给 Go 方法,以便它知道将异常发送到哪里。执行此操作的最佳方法是传递 UI 线程的 SynchronizationContext

像这样的东西会起作用:

public static void Main()
{
    var ui = SynchronizationContext.Current;
    new Thread ( () => Go( ui ) ).Start();
}

static void HandleException( Exception ex )
{
    // this will be run on the UI thread
}

static void Go( SynchronizationContext ui )
{
    try
    {
        // ...
        throw null;    // The NullReferenceException will get caught below
        // ...
    }
    catch (Exception ex) 
    {
        ui.Send( state => HandleException( ex ), null );
    }
}

关于c# - 如何将异常显式传递给 C# 中的主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8776865/

相关文章:

c# - List<T> 及其在表单生命周期内创建并返回到另一个类的项目在销毁后能否继续存在?

c# - asp.net web 表单中的多线程 web 服务调用

c# - 如何解决此 WCF 异常?

c# - 如何在编辑模式 ASP .Net 中将日期选择器放入 Gridview

c# - WCF 请求返回错误响应

java - Future中的get方法在java中是如何工作的?

java - netty 占用了 100% 的 CPU

c# - LINQ-to-entities 泛型 == 解决方法

Python gevent pool.join() 永远等待

java - `JNI_OnLoad` 是否总是在主线程中调用?