【问题标题】:Get result of async method获取异步方法的结果
【发布时间】:2012-03-07 04:05:16
【问题描述】:

我有对 Web 服务进行异步调用的方法。类似的东西:

public static async Task<ReturnResultClass> GetBasicResponseAsync()
{
    var r = await SomeClass.StartAsyncOp();
    return await OtherClass.ProcessAsync(r);
}

我想提供同步替代:

public static ReturnResultClass GetBasicResponse()
{
    return GetBasicResponseAsync().Result;
}

但它会阻止Result 调用。因为它是在与异步操作相同的线程上调用的。如何同步获取结果?

谢谢!

【问题讨论】:

    标签: c# async-await c#-5.0


    【解决方案1】:

    没错,如果您在 GUI 应用程序中,async 方法的延续部分将默认在 UI 线程上执行。而如果同时在UI线程上对同一个Task执行同步等待,就会出现死锁。

    如果是你的应用程序,你可以通过简单地不同步等待任务来解决这个问题。

    如果您只是在编写一个库,您可以使用ConfigureAwait(false) 来解决这个问题。这样,该方法的延续部分将不会在捕获的上下文(GUI 应用程序中的 UI 线程)上执行,而是在 ThreadPool 线程上执行。

    public static async Task<ReturnResultClass> GetBasicResponseAsync()
    {
        var r = await SomeClass.StartAsyncOp().ConfigureAwait(false);
        return await OtherClass.ProcessAsync(r).ConfigureAwait(false);
    }
    

    当然,理想的解决方案是不在您的 GUI 应用程序中使用同步操作并且在您的库中使用 ConfigureAwait(),以便其他人可以根据需要使用方法的同步版本。

    【讨论】:

    • 谢谢! ConfigureAwait 会影响我的 lib 的异步客户端吗?我的意思是,异步操作会保持异步,还是会在所有客户端的其他线程上执行?
    • 是的,它也会影响异步客户端,但在某种程度上应该没问题。异步操作将保持异步,只是使用 ConfigureAwait() 的代码的延续部分不会在 UI 线程上执行。但是在 UI 线程上启动的方法中的任何异步代码都将保留在那里(除非你在那里也使用 ConfigureAwait())。
    猜你喜欢
    • 2014-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    相关资源
    最近更新 更多