概述
.NET基于委托的APM(Asynchronous Programming Model)模型通过BeginInvoke, EndInvoke, AsyncCallback,IAsyncResult的组合使用,让程序员可以方便的进行异步调用、异步回调和同步等待等操作。但.NET平台还没有为线程的中止(abort)提供安全可靠的机制,也许正是基于这个原因APM并没有包含异步调用的超时机制,而是把这个可能引起争议的工作交给使用者自己来把握。
作为APM模型的补充,本文通过CancellableTask类提供了一个异步调用超时机制。CancellableTask类的设计有两个主要的考虑:
1.保持APM风格,使用者依然可以使用熟悉的BeginInvoke, EndInvoke, IAsyncResult, AsyncCallback等;
2.提供基于Thread.Abort的默认超时处理,同时支持用户自定义cancel回调。
使用
CancellableTask的构造函数包含workCallbak和cancelCallback(可选)两参数,分别对应work回调和cancel回调。CancellableTask的BeginInvoke保持了APM的风格,可以看作是增加了timeout参数(单位:ms)的扩展版;而EndInvoke,AsyncCallback以及IAsyncResult的使用都和APM保持一致。Work委托产生的异常会在EndInvoke时抛出,同时若线程被超时中止,EndInvoke则会抛出ThreadAbortException异常。
下面是一段CancellableTask的使用示例:
class Program { static void Main(string[] args) { //默认超时直接abort线程 { Console.WriteLine("[case 1]"); CancellableTask cancellableTask = new CancellableTask(Work); State arg = new State { Loop = 20, Stop = false }; IAsyncResult asyncResult = cancellableTask.BeginInvoke( arg, (ar => Console.WriteLine("Async Callback")), null, 10 * 1000); asyncResult.AsyncWaitHandle.WaitOne(); try { object r = cancellableTask.EndInvoke(asyncResult); Console.WriteLine("return " + r); } catch (ThreadAbortException) { Console.WriteLine("Thread Aborted"); } catch (Exception exp) { Console.WriteLine(exp.ToString()); } } //自定义Cancel回调 { Console.WriteLine(Environment.NewLine + "[case 2]"); CancellableTask cancellableTask = new CancellableTask(Work, Cancel); State arg = new State { Loop = 20, Stop = false }; IAsyncResult asyncResult = cancellableTask.BeginInvoke( arg, (ar => { try { object r = cancellableTask.EndInvoke(ar); Console.WriteLine("return " + r); } catch (ThreadAbortException) { Console.WriteLine("Thread Aborted"); } catch (Exception exp) { Console.WriteLine(exp.ToString()); } } ), arg, 10 * 1000); } Console.ReadLine(); } static object Work(object arg) { State state = arg as State; int i; for (i = 0; i < state.Loop; i++) { if (state.Stop) break; Console.WriteLine(i); Thread.Sleep(1000); } return i; } static void Cancel(object state) { State st = state as State; st.Stop = true; } } internal class State { public int Loop { get; set; } public bool Stop { get; set; } }
以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索console
, 超时机制
, state
, stopped working
, IAsyncResult
, WriteLine
cancel
.net task、asp.net task、asp.net mvc task、.net task 异步、.net 4.0 task,以便于您获取更多的相关知识。