4

下面的例子是我的问题的简化。在新线程中引发异常。如果我没有在线程中处理它,它不会被外部 try/catch 捕获并崩溃我的应用程序。

有什么办法可以保证我捕捉到任何发生的异常。

        try
        {
            new Thread(delegate()
                {
                    throw new Exception("Bleh"); // <--- This is not caught

                }).Start();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }
4

4 回答 4

6

一般来说,在线程本身中捕获异常是最容易的。

但是,如果您想将异常与线程函数本身分开捕获(并且如果您可以使用Task而不是旧Thread方法),您可以编写如下代码:

var task = Task.Factory.StartNew(() =>
{
    throw new Exception("Test");
});

task.ContinueWith(t => handleException(t.Exception), TaskContinuationOptions.OnlyOnFaulted);

这用于ContinueWith()在第一个线程完成并发生异常后调用另一个方法,因此您可以记录异常或其他任何内容:

static void handleException(AggregateException exception)
{
    foreach (var ex in exception.Flatten().InnerExceptions)
        Console.WriteLine(ex.Message);
}

这并不能真正让您解决任何问题——唯一明智的做法是在线程函数本身中正确处理异常。

于 2013-06-25T13:28:34.507 回答
2

我是这样说的,我相信这是最安全的:

 var thread =   new Thread(MyMethod);
 thread.start();

这个方法。try-catch 应该在任何线程方法中

 private void MyMethod()
 {
    try
    {
        {
            throw new Exception("Bleh");//<--- This's not caught => now it is caught :)
        }
    }
    catch (Exception ex)
    {
        Logger.Log(ex.ToString());
    }
}
于 2013-06-25T13:22:58.720 回答
1

使用AppDomain.UnhandledExceptionApplication.ThreadExceptionDispatcher.UnhandledException。这取决于应用程序的实际类型。

另一种可能性是使用 AOP(想到PostSharp )。但是,捕获异常并不是唯一的目标。您需要找到解决异常原因的方法。如果它是一个错误,那么异常是有帮助的并且足够记录。如果有更复杂的原因,您需要考虑并采取对策。不幸的是,没有“通用解决方案”。因此,如果您没有事先捕获异常,我怀疑您能否很好地采取行动。

于 2013-06-25T13:12:03.703 回答
0

据我了解,.Net 不允许在两个线程之间进行通信。因为线程彼此隔离。您可以通过简单的方式实现这一点,我不知道它适合您的程度。如果有用,请标记答案。

public  Exception exception;

private void button1_Click(object sender, EventArgs e)
{
        try
        {
            new Thread(delegate()
            {
                try
                {
                    throw new Exception("Bleh"); // <--- This is not caught
                }
                catch (Exception e)
                {
                    exception = e;
                }

            }).Start();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.ToString());
        }

        if (exception != null)
        {
            //your code here
        }

    }
于 2013-06-25T13:55:47.617 回答