前言
TAP是基于Task的异步编程设计模式,
异步编程
- async : async关键字修饰的方法都会被视为异步方法,编译器会为方法生成一个对应的状态机
- await : await关键字后面代表可等待方法,编译器会转化成TaskAwait去处理异步
async修饰符代表了这个方法是异步方法,编译器会生成状态机。
1 2 3 4 5 6 7 8 9 10
| public async Task MethodAsync() {
await Method1Async();
}
|
异步取消
采用CancellationToken来管理整个取消逻辑
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| CancellationTokenSource source = new CancellationTokenSource(); CancellationToken token = source.Token;
var result await MethodAsync(token);
source.Cancel();
public async Task MethodAsync(CancellationToken token) { source.Cancel();
}
|
TAP转换APM
采用TaskCompletionSource
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public static Task<int> ReadTask(this Stream stream, byte[] buffer, int offset, int count, object state) { var tcs = new TaskCompletionSource<int>(); stream.BeginRead(buffer, offset, count, ar => { try { tcs.SetResult(stream.EndRead(ar)); } catch (Exception exc) { tcs.SetException(exc); } }, state); return tcs.Task; }
|
官方封装了工具类TaskToApm
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| internal sealed class TaskAsyncResult:IAsyncResult{...}
public static IAsyncResult Begin(Task task, AsyncCallback? callback, object? state) => new TaskAsyncResult(task, state, callback);
public static TResult End<TResult>(IAsyncResult asyncResult) { if (GetTask(asyncResult) is Task<TResult> task) { return task.GetAwaiter().GetResult(); }
ThrowArgumentException(asyncResult); return default!; }
public void BeginMethod(AsyncCallback callback,object? ) { TaskToApm.Begin(MethodAsync(),callback,null); }
|
小结
TAP已经让异步编程无感了,就像正常的方法一样,不用再关心如何去处理结果。