Task的在主线程处理异常信息的Helper类
最近使用task时候需要把异常记录日志,直接注入非单例模式的实例进入异步线程,在高并发情况下会出现一些问题。
所以需要把异常反馈给主线程 ,并且不在主线程里进行等待,研究相关资料后,自己写了一个简单的helper类封装了下。
1 using System; 2 using System.Threading; 3 using System.Threading.Tasks; 4 5 namespace Xyfy.Helper 6 { 7 /// <summary> 8 /// 9 /// </summary> 10 public class TaskHelper 11 { 12 /// <summary> 13 /// 14 /// </summary> 15 event EventHandler<AggregateExceptionArgs> AggregateExceptionCatched; 16 17 private readonly TaskFactory factory; 18 19 private readonly Action<Exception> logAction; 20 21 /// <summary> 22 /// 23 /// </summary> 24 /// <param name="errorLogAction"></param> 25 public TaskHelper(Action<Exception> errorLogAction = null) 26 { 27 logAction = errorLogAction ?? Console.WriteLine; 28 AggregateExceptionCatched += new EventHandler<AggregateExceptionArgs>(Program_AggregateExceptionCatched); 29 factory = Task.Factory; 30 } 31 32 /// <summary> 33 /// 34 /// </summary> 35 /// <param name="workAction"></param> 36 /// <returns></returns> 37 public Task StartNew(Action workAction) 38 { 39 return ContinueWith(factory.StartNew(workAction)); 40 } 41 /// <summary> 42 /// 43 /// </summary> 44 /// <param name="task"></param> 45 /// <returns></returns> 46 private Task ContinueWith(Task task) 47 { 48 return task.ContinueWith(t => 49 { 50 if (t.Exception != null) 51 { 52 AggregateExceptionArgs errArgs = new AggregateExceptionArgs() 53 { 54 AggregateException = new AggregateException(t.Exception.InnerExceptions) 55 }; 56 AggregateExceptionCatched(null, errArgs); 57 } 58 }, TaskContinuationOptions.OnlyOnFaulted); 59 } 60 /// <summary> 61 /// 62 /// </summary> 63 /// <param name="action"></param> 64 /// <param name="cancellationToken"></param> 65 /// <returns></returns> 66 public Task StartNew(Action action, CancellationToken cancellationToken) 67 { 68 return ContinueWith(factory.StartNew(action, cancellationToken)); 69 } 70 /// <summary> 71 /// 72 /// </summary> 73 /// <param name="action"></param> 74 /// <param name="creationOptions"></param> 75 /// <returns></returns> 76 public Task StartNew(Action action, TaskCreationOptions creationOptions) 77 { 78 return ContinueWith(factory.StartNew(action, creationOptions)); 79 } 80 /// <summary> 81 /// 82 /// </summary> 83 /// <param name="action"></param> 84 /// <param name="cancellationToken"></param> 85 /// <param name="creationOptions"></param> 86 /// <param name="scheduler"></param> 87 /// <returns></returns> 88 public Task StartNew(Action action, CancellationToken cancellationToken, 89 TaskCreationOptions creationOptions, TaskScheduler scheduler) 90 { 91 return ContinueWith(factory.StartNew(action, cancellationToken, creationOptions, scheduler)); 92 } 93 /// <summary> 94 /// 95 /// </summary> 96 /// <param name="sender"></param> 97 /// <param name="e"></param> 98 private void Program_AggregateExceptionCatched(object sender, AggregateExceptionArgs e) 99 { 100 foreach (Exception item in e.AggregateException.InnerExceptions) 101 { 102 logAction(item); 103 } 104 } 105 106 } 107 }
1 using System; 2 using System.Threading; 3 using System.Threading.Tasks; 4 5 namespace Xyfy.Helper 6 { 7 /// <summary> 8 /// 9 /// </summary> 10 public class AggregateExceptionArgs : EventArgs 11 { 12 /// <summary> 13 /// 14 /// </summary> 15 public AggregateException AggregateException { get; set; } 16 } 17 }