【问题标题】:BackroundWorker - Exception - Don't Close WinForms AppBackroundWorker - 异常 - 不要关闭 WinForms 应用程序
【发布时间】:2017-02-22 18:34:22
【问题描述】:

我有一个运行 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();

【问题讨论】:

  • 如果您没有在某处捕获该异常,框架将终止应用程序。
  • 彼得,你能根据我列出的代码更具体吗?我应该在哪里发现异常?
  • 为什么要注释 UnhandledException 订阅?
  • 为什么要抛出异常?在您处于 UI 线程的 Completed 事件中,只需使用任何错误信息更新 UI。
  • eWorker 将是一个 RunWorkerCompletedEventArgs 对象。我无法想象它永远是空的。

标签: c# multithreading winforms backgroundworker


【解决方案1】:

如果你让异常一直冒泡直到它离开Application.Run() 调用,那么显然这个Application 不能再运行了,你在Application 的范围之外捕获了异常。您需要在您的Form 中捕获异常inside。

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

该处理程序的eWorker 参数由BackgroundWorker 实现提供。您可以放心地依靠它永远不会成为null。您可能要检查的是eWorker 的Result 属性。这将取决于您为DoWorkEventArgs 的Result 属性设置的内容,作为DoWork 处理程序的参数。

例如:

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

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

backgroundWorker1.DoWork += (senderWorker, e) =>
{
    try
    {
        // do something that might throw an exception
    }
    catch(Exception exception)
    {
        e.Result = exception; // this result is passed on to RunWorkerCompleted event
    }
}

【讨论】:

    猜你喜欢
    • 2013-07-09
    • 2012-05-26
    • 2016-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多