我正在创建一个(很好地适应现有的)辅助类,以允许我同步运行async
方法。到目前为止,我已经有了一个任务工厂和一个静态方法,只要我不用async
配置它们就可以同步运行.ConfigureAwait
个方法,因为.ConfigureAwait
会返回返回值从System.Threading.Tasks.Task<T>
到System.Runtime.CompilerServices.ConfiguredTaskAwaitable<T>
的方法。代码如下所示:
public static class AsyncUtils {
private static readonly TaskFactory _taskFactory =
new TaskFactory(
CancellationToken.None,
TaskCreationOptions.None,
TaskContinuationOptions.None,
TaskScheduler.Default
);
public static TResult RunSync<TResult>(Func<Task<TResult>> func) {
return _taskFactory
.StartNew<Task<TResult>>(func)
.Unwrap<TResult>()
.GetAwaiter()
.GetResult();
}
}
如果我尝试添加处理ConfiguredTaskAwaitable<T>
的方法,它可能如下所示:
public static TResult RunSync<TResult>(Func<ConfiguredTaskAwaitable<TResult>> func) {
return _taskFactory
.StartNew<ConfiguredTaskAwaitable<TResult>>(func)
.Unwrap<TResult>() // Doesn't exist!
.GetAwaiter()
.GetResult();
}
问题是,从评论中可以看出,StartNew<ConfiguredTaskAwaitable>
会返回Task<ConfiguredTaskAwaitable<TResult>>
而不是Task<Task<TResult>>
,这意味着Unwrap
方法不存在。有同等的吗?如何为ConfiguredTaskAwaitable
创建等效方法?
答案 0 :(得分:2)
ConfigureAwait()
仅控制在await
之后恢复上下文的方式。如果您同步获得结果,则无效,因为没有“恢复”。
此外,通常只需执行以下操作即可同步运行异步方法:
TResult RunSync<TResult>(Func<Task<TResult>> func) {
return func().Result;
}
或者,如果你想强制它在线程池上运行:
TResult RunSync<TResult>(Func<Task<TResult>> func) {
return Task.Run(func).Result;
}