什么相当于ConfiguredTaskAwaitable的Unwrap?

时间:2016-03-14 15:46:48

标签: c# asynchronous

我正在创建一个(很好地适应现有的)辅助类,以允许我同步运行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创建等效方法?

1 个答案:

答案 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;
}