ReadToEndAsync 正在阻塞,如何异步获取它到 运行?

ReadToEndAsync is blocking, how to get it to run asynchronously?

我从控制器中的异步操作调用此 getJson() 函数。 我有一个大文件列表,每个文件都需要几秒钟的时间供 ReadToEndAsync() 处理。 ReadToEndAsync() 正在阻塞,即使我正在等待它。

如何异步调用 ReadToEndAsync()?

public static async Task<T> getJson<T>(String url)
{
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(server + url);
    HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync();

    String jsonString;
    //get the json string from the response
    using (var xx = response.GetResponseStream())
    {
        StreamReader reader = new StreamReader(xx, Encoding.UTF8);
        jsonString = await reader.ReadToEndAsync()
    }
}

控制器:

_model.list.Add(await DataRetriever.getJson<ReviewModel>(url));
_model.list.Add(await DataRetriever.getJson<ReviewModel>(url));
_model.list.Add(await DataRetriever.getJson<ReviewModel>(url));

如评论中所述,虽然方法 ReadToEndAsync() 确实 而不是 块本身——在词的通常意义上 "block":即,调用该方法的线程继续 运行——它肯定会阻止 await 之后的代码执行,直到该方法完成。这正是您想要的:您不希望该代码在读取完成之前执行,否则它不会有可操作的结果。

您可能应该(重新?)阅读有关 asyncawait 的文档,但简而言之:关键字 async 应用于方法以向编译器发出信号将使用 awaitawait 用于向编译器指示方法中的一个点,编译器应在该点保存方法的当前执行状态 和 return.

如果应用了 await 关键字的操作完成,框架将自动继续执行它停止的方法。在绑定到同步上下文的线程中调用该方法的地方(例如 Winforms 或 WPF 程序中的 GUI 线程),默认情况下此 "continuation" 在该原始线程中执行(但可以在适当的时候禁用它).

请注意上面的 async 方法 returns 来自 await 语句。因此,该方法本身不会阻塞线程,即使该方法表示的操作在某种意义上确实 "block"。


因此,综上所述,在我看来,您可能正在尝试让您的三个操作全部异步并发完成。如果你想这样做,你需要立即启动所有异步操作,而不是像现在一样等待每个操作完成后再继续下一个操作(即通过应用于调用的 await 语句) getJason<T>() 方法)。

看起来像这样:

Task<ReviewModel> task1 = DataRetriever.getJson<ReviewModel>(url1),
    task2 = DataRetriever.getJson<ReviewModel>(url2),
    task3 = DataRetriever.getJson<ReviewModel>(url3);

_model.list.Add(await task1);
_model.list.Add(await task2);
_model.list.Add(await task3);

(注意:在您的原始代码示例中,您只使用了一个 url 值。因为我假设您真的不想只在不同的时间执行相同的查询三次,所以我继续进行更改代码示例,以便每个任务使用不同的值)。

在上面,即使第二个and/or第三个任务先于第一个任务完成,结果也会按顺序添加到结果列表中。 但是任务本身是同时启动的,因此它们可以运行并发。


我希望以上内容不仅能为您阐明对方法 ReadToEndAsync() 的调用是否阻塞(它不会,尽管由于调试器呈现代码执行的方式,它可能 seem 它确实如此),但也为您提供了解决导致您调试该方法的更大问题的方法,认为 它正在阻塞。 IE。您的 JSON 查询没有同时执行。

如果在对您的问题发表评论和上面的回答之间,您仍然遇到问题,请编辑您的问题,以便更清楚地了解您到底在问什么。