【问题标题】:Async and Await with HttpWebRequest.GetResponseAsync使用 HttpWebRequest.GetResponseAsync 进行异步和等待
【发布时间】:2012-10-03 03:37:07
【问题描述】:

我在发出 Web 请求时尝试使用 Async 和 Await,但发现它永远不会超过 await 行。我是通过 Metro 应用程序执行此操作的,但我也在 winforms 应用程序中验证了问题。

public async Task<string> DoSomething()
{
    string url = "http://imgur.com/gallery/VcBfl.json";
    HttpWebRequest request = HttpWebRequest.CreateHttp(url);

    var ws = await request.GetResponseAsync();

    return ws.ResponseUri.ToString(); ;
}

如果我不使用 await 而是执行同步等待,它可以工作,但我需要它异步运行。

我在这段代码中遗漏了什么导致等待永远不会返回?

【问题讨论】:

    标签: c# windows-8 windows-runtime httpwebrequest async-await


    【解决方案1】:

    我怀疑在调用堆栈的更深处,您在返回的 Task 上调用 WaitResultThis will cause a deadlock, as I describe on my blog.

    遵循这些最佳做法以避免死锁:

    1. 不要阻止async 代码;一直使用async
    2. 在您的“库”方法中,使用ConfigureAwait(false)

    【讨论】:

    • 谢谢。就是这样。感谢您的链接,它非常有帮助。
    • @Stephen,感谢您的博文!澄清问题:如果我在我的库中使用.ConfigureAwait(false)(基本上是一个WebClient),那么我可以在调用它时使用.Result吗?它似乎有效,但我不知道当我把它放在野外时会发生什么。
    • @Brad:是的,只要你调用的异步方法做同样的事情。但是,使用Result 并不是最佳实践;总有更好的选择。
    • @Stephen,我调用的异步方法返回一个任务并且不调用结果。有问题的代码是用于调用内部 API 的自定义包装器,并且我想在实际的 GET/POST 方法(GetRequestStreamAsync、GetResponseAsync 等)中进行异步的唯一部分。我如何保持这个异步而不使这个和控制器操作之间的每个方法都异步并返回一个任务?我希望 lib 能够处理异步性质并让消费者保持不可知论。
    • @Brad:由于异步代码的性质,这是不可能的。最好一直使用异步。
    猜你喜欢
    • 2020-09-11
    • 2023-03-30
    • 2019-02-10
    • 2019-07-29
    • 2015-07-27
    • 2013-08-01
    • 1970-01-01
    • 2017-05-11
    相关资源
    最近更新 更多