在单独的线程上捕获未处理的异常

时间:2010-11-26 11:44:23

标签: c# exception-handling

我正在使用以下事件来捕获主UI线程中的未处理异常。

Application.ThreadException 

不幸的是,它没有在单独的线程中捕获那些未处理的错误。我知道

AppDomain.CurrentDomain.UnhandledException

但是,这似乎会在触发时关闭应用程序,而前者则不会。

有没有办法在单独的线程上处理未处理的异常,而不关闭应用程序?

3 个答案:

答案 0 :(得分:24)

@Ani已经回答了你的问题。虽然我不同意线程中未处理的异常应该终止应用程序。使用线程通常意味着您拥有某种服务器应用程序。把它搞砸可能会导致很多愤怒的用户。

我写了一篇关于正确异常处理的小文章:http://blog.gauffin.org/2010/11/do-not-catch-that-exception/

您应始终捕获线程的异常。我通常使用以下模式:

  void ThreadMethod(object state)
  {
      try
      {
          ActualWorkerMethod();
      }
      catch (Exception err)
      {
          _logger.Error("Unhandled exception in thread.", err);
      }
  }

  void ActualWorkerMethod()
  {
      // do something clever
  }

通过将逻辑移动到单独的方法并将try / catch块保留在线程方法中,找到不能正确处理异常的线程方法要容易得多。

答案 1 :(得分:3)

当然,您应该始终处理所有异常。但是,如果您目前无法执行此操作,则可以尝试以下操作:

应用程序将在import { withRouter } from 'react-router'; ... handleSubmit = () => { ... this.props.history.push('/moneyform'); } render() { return ( <ReactFragment> <div> ... </ReactFragment> ) } export default withRouter(confirmWithdraw); 事件处理程序之后 崩溃/关闭。 您可以在事件处理程序中添加一个延迟来防止这种情况。没有例外的其他线程(例如主线程)可以继续。因此,该应用程序将不会关闭并且可以继续。但是,具有异常的线程将保持睡眠状态。因此,您可能会遇到“内存/线程泄漏”的情况。

BUILD SUCCESSFUL in 3s
27 actionable tasks: 1 executed, 26 up-to-date
Running C:\Users\Rebecca|AppData\Local\Android|sdk/platform-tools/adb -s emulato
r-5554 reverse tcp:8081 tcp:8081
Could not run adb reverse: spawnSync C:\Users\Rebecca|AppData\Local\Android|sdk/
platform-tools/adb ENOENT
Starting the app on emulator-5554 (C:\Users\Rebecca|AppData\Local\Android|sdk/pl
atform-tools/adb -s emulator-5554 shell am start -n com.albums/com.albums.MainAc
tivity)...

D:\Projects\ReactNative\albums>adb devices
List of devices attached
emulator-5554   device

目前没有更好的解决方案。 您可能会发现更改配置文件,但我认为这同样肮脏:https://stackoverflow.com/a/15348736

答案 2 :(得分:2)

是的,您必须手动捕获线程上的异常。

但是,这段代码:

void ThreadMethod(object state)
{
    try
    {
        ActualWorkerMethod();
    }
    catch (Exception err)
    {
        _logger.Error("Unhandled exception in thread.", err);
    }
}

void ActualWorkerMethod()
{
    // do something clever
}

可以使用PostSharp简化为此:

[LogExceptions]
void ActualWorkerMethod()
{
    // do something clever
}