C# 如何在主流程中处理BackgroundWorker异常?

C# 如何在主流程中处理BackgroundWorker异常?,c#,winforms,exception,backgroundworker,C#,Winforms,Exception,Backgroundworker,我想在我的Progress类中处理所有未处理的异常,我在该类中编写了一些错误日志代码: static class Program { /// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { try { Appli

我想在我的
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.                
        }
    }
}

我希望在我的
进度
类中处理异常“我得到了…”,但当我运行(而不是调试)应用程序时,系统会显示异常对话框。

在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);
}

您的表单代码应该可以使用它,并且您应该在程序的运行模式(ctrl+F5)下获得
AppDomain.UnhandledException
MessageBox

。请执行以下操作:

[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);
}

您的表单代码应该可以使用它,并且您应该在运行模式(ctrl+F5)下获得
AppDomain.UnhandledException
MessageBox

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

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();
    }
}

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

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

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();
    }
}

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

我不认为这个问题是专门针对BackgroundWorker的。我想您想知道如何处理Windows窗体事件处理程序中抛出的异常。我在应用程序的某个位置尝试了“抛出新异常(“测试”),所有这些异常都由Prograss类中的代码正确处理。但是当涉及到backgroundworker时,“我得到了…”异常无法正确处理。无法准确再现,但显然是由调用的已完成事件引起的。AppDomain和AppUnhandled处理程序中的解决方法。我不认为这个问题是BackgroundWorker特有的。我想您想知道如何处理Windows窗体事件处理程序中抛出的异常。我在应用程序的某个位置尝试了“抛出新异常(“测试”),所有这些异常都由Prograss类中的代码正确处理。但是当涉及到backgroundworker时,“我得到了…”异常无法正确处理。无法准确再现,但显然是由调用的已完成事件引起的。AppDomain和AppUnhandled-handlers中的解决方法。谢谢!但还是有问题。您是否试过运行(而不是调试)该应用程序?当我调试程序时,它可以正常工作,但运行它时仍然会出现相同的错误。你是对的,我编辑了代码,我认为它是这样工作的。主函数中的try/catch不起作用,因为它是一个不同的线程,要捕获异常,您需要
AppDomain.UnhandledException
事件,正如shalongbus指出的,我用您的答案解决了我的问题,谢谢!函数AppDomain\u UnhandledException不是必需的,设置unhandledExcepionMode就足够了,因为我已经编写了一些异常日志记录代码。谢谢!但还是有问题。您是否试过运行(而不是调试)该应用程序?当我调试程序时,它可以正常工作,但运行它时仍然会出现相同的错误。你是对的,我编辑了代码,我认为它是这样工作的。主函数中的try/catch不起作用,因为它是一个不同的线程,要捕获异常,您需要
AppDomain.UnhandledException
事件,正如shalongbus指出的,我用您的答案解决了我的问题,谢谢!函数AppDomain_UnhandledException不是必需的,设置unhandledExcepionMode就足够了,因为我已经编写了一些异常日志记录代码。