WinForms异常拦截器

时间:2017-09-14 15:42:22

标签: winforms asynchronous exception-handling interceptor aspnetboilerplate

我正在使用带有WinForms的ABP框架,我需要找出拦截异常并记录此信息的最佳方法。

我的WinForms是一个多文档界面(MDI)应用程序。我在 Program.cs 中添加HandleException,以便在应用程序抛出异常时,我可以将其记录在日志文件中。但是如果我在ApplicationService中得到一个异常,这个异常由ABP处理而不会被抛回WinForms,并且没有任何内容写入日志文件。

我是否需要实现一些接口来获得像MVC / Angular app这样的经典日志?

更新

我发现问题与异步操作有关。通常我打电话:

await _service.GetProducts();

如果抛出异常,主线程不会拦截它。如果我切换到:

AsyncHelper.RunSync(() => _service.GetProducts());

然后主线程拦截错误。

2 个答案:

答案 0 :(得分:0)

因为在另一个线程中抛出异常,您必须处理应用程序域的未处理异常。将异常处理程序插入应用程序的起始点。对于win表单,我猜你可以使用program.cs

static class Program
{
  [STAThread]
  static void Main(string[] argv)
  {
    try
    {
      AppDomain.CurrentDomain.UnhandledException += (sender,e)
      => HandleException(e.ExceptionObject);

      Application.ThreadException += (sender,e)
      => HandleException(e.Exception);


      Application.Run(new MainWindow());
    }
    catch (Exception ex)
    {
      HandleException(ex);
    }
  }

  static void HandleException(object exception) {
    var ex= exception as Exception;
    if (ex== null) {
         ex= new NotSupportedException("Unhandled exception: " + exceptionObject.ToString());
    }

    //you can log exception here -> ex.ToString();
  }
}

答案 1 :(得分:0)

在进行了一些调查和谷歌搜索之后,我发现了这个MSDN解释Asynchronous Programming - Async from the Start

根据这篇文章我改变我的程序开始转移到异步代码。 我需要更多一点,因为我在打开内部表格时使用Mdi表格

Form1 childForm = Globals.Bootstrapper.IocManager.Resolve<Form1>();
        childForm.MdiParent = this;
        var formAsync = childForm.InitializeAsync();
        FormExtension.HandleExceptions(formAsync);
        childForm.Show();

我添加静态类来拦截错误形式Abp

public static async void HandleExceptions(Task task)
    {
        try
        {
            await Task.Yield(); //ensure this runs as a continuation
            await task;
        }
        catch (Exception ex)
        {
            //deal with exception, either with message box
            //or delegating to general exception handling logic you may have wired up 
            //e.g. to Application.ThreadException and AppDomain.UnhandledException
            var log = Globals.Bootstrapper.IocManager.IocContainer.Resolve<ILogger>();
            LogHelper.LogException(log, ex);
            //Exception handling...
            MessageBox.Show("Ops!" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            //Application.Exit();
        }
    }

现在我的日志文件以正确的方式填充