线程化时的异常 - 线程之间的传播?

Joh*_*0te 4 .net c# multithreading exception .net-3.5

如果我有以下情况:

  1. Execute()创建一个新线程并在其中执行函数GetSession().
  2. Execute()在它自己的线程中再次执行GetSession().
  3. Execute()从(1)加入线程.

我的问题是:

如果GetSession()从(1)中生成的线程抛出异常,而运行线程Execute()当前正在运行GetSession()本身会发生什么?

从额外线程重新抛出的异常是否会传播到Execute()并导致它转到其处理程序,即使它来自不同的线程?


以下是一些示例代码来演示此问题:

我刚刚在这里的窗口中做了这个(它是一个模型),所以对语法错误有所了解.

public void Execute()
{
    //Some logon data for two servers.
    string server1 = "x", server2 = "y", logon = "logon", password = "password";

    //Varialbes to store sessions in.
    MySession session1, session2;

    try
    {
        //Start first session request in new thread.
        Thread thread = new Thread(() =>
            session1 = GetSession(server1, logon, password));
        thread.Start();

        //Start second request in current thread, wait for first to complete.
        session2 = GetSession(server2, logon, password));
        thread.Join();
    }
    catch(Exception ex)
    {
        //Will this get hit if thread1 throws an exception?
        MessageBox.Show(ex.ToString());
        return;
    }
}

private MySession GetSession(string server, string logon, string password)
{
    try
    {
        return new MySession(server, logon, password);
    }
    catch(Exception Ex)
    {
        throw(Ex);
    }
}
Run Code Online (Sandbox Code Playgroud)

Ree*_*sey 5

如果GetSession()从(1)中生成的线程抛出异常,而运行线程Execute()当前正在运行GetSession()本身会发生什么?

线程版本将引发未处理的异常,这将触发AppDomain.UnhandledException.除非在那里明确处理,否则它将拆除应用程序.

从额外线程重新抛出的异常是否会传播到Execute()并导致它转到其处理程序,即使它来自不同的线程?

不,它将无法处理.


请注意,这是TPL的优势之一.如果您使用Task而不是Thread,可以将此异常传回主线程:

try
{
    //Start first session request in new thread.
    Task<Session> task = Task.Factory.StartNew(() => GetSession(server1, logon, password));

    //Start second request in current thread, wait for first to complete.
    session2 = GetSession(server2, logon, password));
    session1 = task.Result; // This blocks, and will raise an exception here, on this thread
}
catch(Exception ex)
{
    // Now this will get hit
    MessageBox.Show(ex.ToString());
    return;
}
Run Code Online (Sandbox Code Playgroud)

但请注意,这将是一个AggregateException,需要特殊处理.