BackroundWorker - 例外 - 不要关闭WinForms应用程序

时间:2017-02-22 18:34:22

标签: c# multithreading winforms backgroundworker

我有一个运行BackgroundWorker的简单WinForms应用程序。

以下是我附加异常处理程序的主要内容。

static class Program
{
    private static Logger _logger = LogManager.GetCurrentClassLogger();

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.ThreadException += OnThreadException;
        //Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
       // AppDomain.CurrentDomain.UnhandledException += OnUnhandledException;

        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);

        try
        {
            Application.Run(new Form());
        }
        catch (Exception exc)
        {
            LogFatalException(exc);
        }
    }

    private static void OnUnhandledException(object sender, UnhandledExceptionEventArgs e)
    {
        if (e.IsTerminating)
        {
            _logger.Info("Application is terminating due to an unhandled exception in a secondary thread.");
        }
        LogFatalException(e.ExceptionObject as Exception);
    }

    private static void OnThreadException(object sender, ThreadExceptionEventArgs e)
    {
        LogFatalException(e.Exception);
    }

    private static void LogFatalException(Exception exc)
    {
        _logger.Error(exc, exc.Message);

        MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

我正在调用我的BackgroundWorker,如下所示。我希望后台线程上发生的任何类型的异常都冒泡到主处理方法和日志/警报但不关闭应用程序。

我做错了什么?申请仍在关闭。

backgroundWorker1.RunWorkerCompleted += (senderWorker, eWorker) =>
{
    if (eWorker != null)
    {
        throw new Exception("Error Processing. Please check connection and try again.");
    }
};

backgroundWorker1.RunWorkerAsync();

1 个答案:

答案 0 :(得分:0)

如果你让异常气泡一直持续到Application.Run()调用,那么显然这个Application不能再运行了,你在Application&& #39;范围。您需要在<{1}} 中捕获内的异常。

但这里真的没有必要。当您到达Form处理程序时,您已经回到了UI线程。您可以评估后台进程的结果,并在UI上显示足够的错误消息。

该处理程序的RunWorkerCompleted参数由eWorker实现提供。你可以安全地依赖它BackgroundWorker。您可能想要检查的是null的{​​{1}}属性。这将取决于您设置为Result属性的eWorker属性,作为Result处理程序的参数。

例如:

DoWorkEventArgs

并且您的DoWork处理程序可能如下所示:

backgroundWorker1.RunWorkerCompleted += (senderWorker, eWorker) =>
{
    if (eWorker.Result != null)
    {
         MessageBox.Show("Process result: " + eWorker.Result.ToString())
    }
}