.NET中,我们System.Threading.tasks命名空间执行异步操作。另外,C#提供了async和await关键字,允许你用顺序的编程模型执行异步操作,这就大幅度地简化了代码。来看一下C#开发人员如何使用异步的winrt api。
下面的代码用WinrtasyncIntro 重新写了,但是,这个版本引入了一些.net框架的映射(扩展方法),这段代码不提供进度汇报(因为GetFileasync 不提供)且忽略了取消:
namespace System {
public static class WindowsRuntimeSystemExtensions {
public static TaskAwaiter GetAwaiter(
this IAsyncAction source);
public static TaskAwaiter GetAwaiter<TProgress>(
this IAsyncActionWithProgress<TProgress> source);
public static TaskAwaiter<TResult> GetAwaiter<TResult>(
this IAsyncOperation<TResult> source);
public static TaskAwaiter<TResult> GetAwaiter<TResult, TProgress>(
this IAsyncOperationWithProgress<TResult, TProgress> source);
}
}
C#的await操作符引起了编译器在IasyncOperation<StorageFile>接口中寻找Getawaiter方法。接口不提供Getawaiter方法,所以编译器找扩展方法,幸运的是,.net框架team已经提供了一组扩展方法,可以被winrt的IasyncXxx 接口调用:
namespace System {
public static class WindowsRuntimeSystemExtensions {
public static Task AsTask<TProgress>(this IAsyncActionWithProgress<TProgress> source,
CancellationToken cancellationToken, IProgress<TProgress> progress);
public static Task<TResult> AsTask<TResult, TProgress>(
this IAsyncOperationWithProgress<TResult, TProgress> source,
CancellationToken cancellationToken, IProgress<TProgress> progress);
// Simpler overloads not shown here
}
}
在内部,所有这些方法构造一个taskCompletionSource然后告诉IasyncXxx 对象去调用回调,然后当异步操作完成时设置taskCompletionSource的最终状态。taskawaiter 对象从这些扩展方法返回的其实就是C#的await。当异步操作完成时,taskawaiter确保代码继续通过SynchronizationContext 执行并关联到原来那个线程。如果调用的线程是GUI线程,这段代码返回到GUI线程。然后这个线程执行C#编译器生成的代码,查询 taskCompletion- Source任务的result属性。