0

假設我有一個主要方法的控制檯應用程序,這樣的事情:從處理異常不期待已久的任務

public static void Main(string[] args) 
{ 
    AppDomain.CurrentDomain.UnhandledException += (sender, eventArgs) => 
    { 
     Console.WriteLine("App Unobserved"); 
    }; 
    TaskScheduler.UnobservedTaskException += (sender, eventArgs) => 
    { 
     Console.WriteLine("Task Unobserved"); 
    }; 
    Task.Run(async() => await MyAwesomeMethod()); 
    // other awesome code... 
    Console.ReadLine(); 
} 

public static async Task MyAwesomeMethod() 
{ 
    // some useful work 
    if (something_went_wrong) 
     throw new Exception(); 
    // other some useful work 
} 

所以,我只需運行MyAwesomeMethod(發射後不管),而要想做到一些其他的工作,但我也想知道是否有任何未處理的例外。但是,應用程序成功完成,沒有任何問題跡象(異常只是被吞噬)。

如何從MyAwesomeMethod()處理異常,而無需等待或使用Task.Run(...)。Wait()?

+2

'但是我也想知道是否有任何未處理exceptions.' - 那就不是真正的火災和忘記,是嗎? –

+0

沒有理由在線程池線程中啓動另一個異步操作。如果你想開始'MyAswsomeMethod'然後調用'MyAwesomeMethod'。它*已經*異步。將其包裝在異步lambda中並在線程池線程中啓動它們都只會浪費系統資源。 – Servy

+0

@Servy實際上,有一個原因:如果一切正常,我不想知道MyAwesomeMethod的任何內容,但我想知道關於未處理異常的所有信息。 – Andrew

回答

1

所以,我只是運行MyAwesomeMethod(fire-and-forget)...但我也想知道是否有任何未處理的異常。但是,應用程序成功完成,沒有任何問題跡象(異常只是被吞噬)。

那不是「火災和遺忘」,那麼。 「火和忘記」的字​​面意思是你不在乎何時(或是否)任務完成(或錯誤)。

如何從MyAwesomeMethod()處理異常,而無需等待或使用Task.Run(...)。Wait()?

使用await反正:

Task.Run(async() => { 
    try { 
    await MyAwesomeMethod(); 
    } catch (Exception ex) { 
    Console.WriteLine(ex); 
    } 
}); 
0

例如,您可以將代碼包裝在後臺任務中的try ... catch塊中,並在您進入catch塊(如果有)時立即生成一個事件。

event EventHandler<Exception> exceptionInWorker; 

,並在做任務

try 
{ 
    //do something 
} 
catch (Exception e) 
{ 
    exceptionInWorker?.Invoke(this, e); 
} 
0

您可以檢查任務的status一旦它完成。

Task.Run(() => MyAwesomeMethod()).ContinueWith((task) => 
{ 
    if (task.Status == TaskStatus.RanToCompletion && task.Result != null) 
    { 

    } 
    else 
    { 
     try 
     { 
      Logger.LogError(task.Exception.ToString()); 
      Logger.LogMessage("something_went_wrong"); 
     } 
     catch { } 
    } 
}); 
+0

好吧,thx,好的嘗試:)如果我找不到其他解決方案,我會使用它。 – Andrew

+0

玩這個狀態並在你的AwesomeMethod函數中返回一些東西! – billybob

-2

您可以訂閱TaskScheduler.UnobservedTaskException活動爲你做,但與處理程序,需要UnobservedTaskExceptionEventArgs作爲其第二個參數,通過它,你可以通過它的異常屬性訪問未處理的異常並記錄所有關於它的信息。

+0

這就是他剛剛在他的問題中所寫的內容...... – billybob

+0

那麼他訂閱了它,但沒有做什麼與例外。處理程序應該將UnobservedTaskExceptionEventArgs作爲其第二個參數,通過它可以通過其Exception屬性訪問未處理的異常。並記錄有關它的所有信息。 –