运行结果如下图所示,与预期结果一致。其中使用了task.Status来打印任务运行的状态,对于task.Status的状态具体含义如下表所示。
成员名称 说明Canceled 该任务已通过对其自身的 CancellationToken 引发 OperationCanceledException 对取消进行了确认,此时该标记处于已发送信号状态;或者在该任务开始执行之前,已向该任务的 CancellationToken 发出了信号。 有关详细信息,请参阅任务取消。
Created 该任务已初始化,但尚未被计划。
Faulted 由于未处理异常的原因而完成的任务。
RanToCompletion 已成功完成执行的任务。
Running 该任务正在运行,但尚未完成。
WaitingForActivation 该任务正在等待 .NET Framework 基础结构在内部将其激活并进行计划。
WaitingForChildrenToComplete 该任务已完成执行,正在隐式等待附加的子任务完成。
WaitingToRun 该任务已被计划执行,但尚未开始执行。
1.5 将APM模式转换为任务
在前面的章节中,介绍了基于IAsyncResult接口实现了BeginXXXX/EndXXXX方法的就叫APM模式。APM模式非常古老,那么如何将它转换为TAP模式呢?对于常见的几种APM模式异步任务,我们一般选择使用Task.Factory.FromAsync()方法来实现将APM模式转换为TAP模式。
演示代码如下所示,比较简单不作过多介绍。
static void Main(string[] args) { int threadId; AsynchronousTask d = Test; IncompatibleAsychronousTask e = Test; // 使用 Task.Factory.FromAsync方法 转换为Task WriteLine("Option 1"); Task<string> task = Task<string>.Factory.FromAsync(d.BeginInvoke("异步任务线程", CallBack, "委托异步调用"), d.EndInvoke); task.ContinueWith(t => WriteLine($"回调函数执行完毕,现在运行续接函数!结果:{t.Result}")); while (!task.IsCompleted) { WriteLine(task.Status); Sleep(TimeSpan.FromSeconds(0.5)); } WriteLine(task.Status); Sleep(TimeSpan.FromSeconds(1)); WriteLine("----------------------------------------------"); WriteLine(); // 使用 Task.Factory.FromAsync重载方法 转换为Task WriteLine("Option 2"); task = Task<string>.Factory.FromAsync(d.BeginInvoke,d.EndInvoke,"异步任务线程","委托异步调用"); task.ContinueWith(t => WriteLine($"任务完成,现在运行续接函数!结果:{t.Result}")); while (!task.IsCompleted) { WriteLine(task.Status); Sleep(TimeSpan.FromSeconds(0.5)); } WriteLine(task.Status); Sleep(TimeSpan.FromSeconds(1)); WriteLine("----------------------------------------------"); WriteLine(); // 同样可以使用 FromAsync方法 将 BeginInvoke 转换为 IAsyncResult 最后转换为 Task WriteLine("Option 3"); IAsyncResult ar = e.BeginInvoke(out threadId, CallBack, "委托异步调用"); task = Task<string>.Factory.FromAsync(ar, _ => e.EndInvoke(out threadId, ar)); task.ContinueWith(t => WriteLine($"任务完成,现在运行续接函数!结果:{t.Result},线程Id {threadId}")); while (!task.IsCompleted) { WriteLine(task.Status); Sleep(TimeSpan.FromSeconds(0.5)); } WriteLine(task.Status); ReadLine(); } delegate string AsynchronousTask(string threadName); delegate string IncompatibleAsychronousTask(out int threadId); static void CallBack(IAsyncResult ar) { WriteLine("开始运行回调函数..."); WriteLine($"传递给回调函数的状态{ar.AsyncState}"); WriteLine($"是否为线程池线程:{CurrentThread.IsThreadPoolThread}"); WriteLine($"线程池工作线程Id:{CurrentThread.ManagedThreadId}"); } static string Test(string threadName) { WriteLine("开始运行..."); WriteLine($"是否为线程池线程:{CurrentThread.IsThreadPoolThread}"); Sleep(TimeSpan.FromSeconds(2)); CurrentThread.Name = threadName; return $"线程名:{CurrentThread.Name}"; } static string Test(out int threadId) { WriteLine("开始运行..."); WriteLine($"是否为线程池线程:{CurrentThread.IsThreadPoolThread}"); Sleep(TimeSpan.FromSeconds(2)); threadId = CurrentThread.ManagedThreadId; return $"线程池线程工作Id是:{threadId}"; }运行结果如下图所示。