0

我正在使用WinForms的ABP框架,我需要確定攔截異常並記錄此信息的最佳方法。WinForms異常攔截器

我的WinForms是一個多文檔界面(MDI)應用程序。我在Program.cs中添加一個HandleException,這樣當應用程序拋出一個異常時,我可以將它記錄在日誌文件中。但是,如果我在ApplicationService中遇到異常,則此異常由ABP處理並且不會返回到WinForms,並且沒有任何內容寫入日誌文件。

我是否需要實現一些接口來使經典日誌記錄像MVC/Angular應用程序?

UPDATE

我發現問題與異步操作。通常我打電話:

await _service.GetProducts(); 

如果引發異常,主線程不會攔截它。如果我切換到:

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

然後主線程攔截錯誤。

回答

0

因爲在另一個線程中拋出異常,您必須處理應用程序域的未處理的異常。將異常處理程序插入到應用程序的起點。對於勝利的形式我想你可以使用的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(); 
    } 
} 
+0

@Albert thk您的建議,但以這種方式,您不能攔截異步異常 – andmattia

0

一些invastigation確定後和谷歌上搜索,我發現這個MSDN解釋Asynchronous Programming - Async from the Start

Accoriding這篇文章我改變我的計劃開始移動到異步代碼。 我需要恰克多一點點,因爲我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(); 
     } 
    } 

現在我的日誌文件以正確的方式填充

+0

這看起來不像是實現該問題的簡便方法。這裏的攔截在哪裏?你只需圍繞任務創建一個try-catch。在攔截過程中,您必須在實際功能之前或之後執行某些操作! –