通过参数可以看到,这个转换Task的过程支持调用方法传入的取消和进度报告。如果我们需要调用的WinRT异步方法的过程中支持取消和进度报告,就不能直接await那个异步方法(相当于调用了默认无参的AsTask的返回task上的GetAwaiter方法),而是应该await显示调用的AsTask(可以传入CancellationToken及IProgress参数的重载,上面那个)返回的task对象。这个可以见本小节末尾处的例子。
回头看一下上面给出的AsTask的实现。里面一个最终要的对象就是TaskToAsyncOperationWithProgressAdapter<TResult, TProgress>,其可以由IAsyncOperationWithProgress<TResult, TProgress>直接转型而来。它也是IAsyncOperationWithProgress<TResult, TProgress>和Task之间的一个桥梁。这个类的工作主要由其父类TaskToAsyncInfoAdapter<TCompletedHandler, TProgressHandler, TResult, TProgressInfo>来完成。这个父类的实现就比较复杂了,但道理都是相同的。有兴趣的同学自行查看其实现吧。
了解了原理最后来看一下代码示例,WinRT中所有的IO相关的类中只提供异步方法,示例因此也选择了这个使用最广泛的功能(示例代码来源是某开源库,具体是啥忘了,有轻微改动):
public async Task<string> ReadTextAsync(string filePath) { var text = string.Empty; using (var stream = await ReadFileAsync(filePath)) { using (var reader = new StreamReader(stream)) { text = await reader.ReadToEndAsyncThread(); } } return text; }有了async/await和上文介绍的扩展方法的支持,C#调用WinRT的异步接口和使用.NET中的异步接口一样的简单。