4

如果我有以下情况:

  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);
    }
}
4

1 回答 1

5

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

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

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

不,它不会被处理。


请注意,这是 TPL 的优势之一。如果您使用任务而不是线程,则可以将异常传播回主线程​​:

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;
}

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

于 2012-07-18T15:55:35.623 回答