[英]Scheduling asynchronous jobs/tasks (and ignoring exceptions) using Observable.Timer
[英]Centralizing exceptions from asynchronous tasks
我在MVC應用程序中實現了自定義HandleErrorAttribute
,並且在某種程度上集中並捕獲應用程序中發生的所有異常一直非常HandleErrorAttribute
。
public class CustomHandleErrorAttribute : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
....
}
}
問題是:我已經開始實現一些異步任務,例如:
Task.Factory.StartNew(() => DoSomethingAsync());
並意識到我的CustomHandleErrorAttribute
不會攔截那些方法中發生的異常:在這種情況下,如果DomeSomethingAsync()
方法內部發生了異常,則我的HandleErrorAttribute
將無法捕獲該HandleErrorAttribute
。 和Global.asax
不會。
有什么好的方法可以集中化異步任務中發生的異常? 我不想在每種方法中實現一個簡單的try / catch塊:我想用某種捕獲它們的處理程序來計數。
一個好的方法是不要使用Task.Factory.StartNew
,尤其是不要在異步方法上使用。
只需直接調用async方法並等待返回的任務即可。 該任務中的異常將通過與其他所有異常相同的機制來重新拋出和處理:
await DoSomethingAsync();
Task.Factory.StartNew
對於將工作卸載到ThreadPool
線程很有用,但是您已經在ThreadPool
線程上,因此Task.Factory.StartNew
。
如果您要放棄該任務,則應該意識到並不能保證它將繼續運行。 任務運行時可以回收應用程序池,因為沒有任何等待。
如果要在asp.net中執行“即發即忘”操作 ,則應使用類似HangFire的方法(有關Fire和ASP.NET上的 “忘記”的更多信息)
在asp.net之外的世界中,您可以使用ContinueWith
和TaskContinuationOptions.OnlyOnFaulted
來簡單地添加一個處理程序作為延續,以確保它僅在有例外的情況下運行,例如使用擴展方法:
public static void HandleExceptions(this Task task)
{
task.ContinueWith(
faultedTask => HandleException(faultedTask.Exception),
TaskContinuationOptions.OnlyOnFaulted);
}
並像這樣使用它:
DoSomethingAsync().HandleExceptions();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.