如何处理主进程中BackgroundWorker的异常

本文关键字:进程 BackgroundWorker 异常 何处理 处理 | 更新日期: 2023-09-27 18:10:03

我想处理我的Progress类中所有未处理的异常,其中我编写了一些用于错误记录的代码:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        try
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new LoginPoint());
        }
        catch (Exception myException)
        {
            //log the unhandled exceptions.                
        }
    }
}

但是BackgroundWorker中的异常没有被正确处理:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    throw new Exception("TEST EXCEPTION!");
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error != null)
    {
        throw new Exception("I GOT THE EXCEPTION");
    }
}

我想要异常"I GOT…"在我的Progress类处理,但系统的异常对话框出现,当我运行(不调试)的应用程序

如何处理主进程中BackgroundWorker的异常

可以使用AppDomain。UnhandledException事件

在program.cs中这样做:

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    AppDomain.CurrentDomain.UnhandledException += AppDomain_UnhandledException;
    Application.SetUnhandledExceptionMode(UnhandledExceptionMode.ThrowException);
    Application.Run(new Form1());
}
static void AppDomain_UnhandledException(Object sender, UnhandledExceptionEventArgs e)
{
    MessageBox.Show(((Exception)e.ExceptionObject).Message, "AppDomain.UnhandledException");
    Environment.Exit(-1);
}

你的表单代码应该与此工作,你应该得到AppDomain.UnhandledException MessageBox在运行模式(ctrl+F5)

我的方法可能是事件处理程序。你面临的问题是跨线程的交流,这是一个臭名昭著的问题!您应该研究线程和调用来了解更多有关这方面的信息。但是,您可以使用事件和事件处理程序在工作线程和主线程之间安全地通信。下面是一个简单的例子:

public delegate void ExceptionHandler(Exception ex);
public class Worker : BackgroundWorker
{
    ExceptionHandler Handler { get; set; }
    public Worker(ExceptionHandler handler)
    {
        Handler = handler;
    }
    protected override void OnDoWork(DoWorkEventArgs e)
    {
        for (var i = 0; i < (int)e.Argument; i++)
        {
            if (i%2 != 0) continue;
            try
            {
                throw new ArgumentException(String.Format("{0}:{1}", i, "TEST EXCEPTION"));
            }
            catch (Exception ex)
            {
                if (this.Handler != null)
                    Handler.Invoke(ex);
            }
        }
    }
}
class Program
{
    public static void HandleException(Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
    static event ExceptionHandler Handler;
    static void Main(string[] args)
    {
        Handler = new ExceptionHandler(HandleException);
        var worker = new Worker(Handler);
        worker.RunWorkerAsync(100);
        Console.ReadLine();
    }
}

控制台窗口的预期输出将是:

0:TEST EXCEPTION
2:TEST EXCEPTION
4:TEST EXCEPTION
6:TEST EXCEPTION
etc etc

希望这对你有帮助,即使这不是你想要的答案,也希望能对你有所帮助。