【发布时间】:2016-09-11 18:06:02
【问题描述】:
我正在查看 http://www.dotnetperls.com/async 上的示例以更好地理解 async/await,但以下内容让我感到困惑:
我理解为什么下面的示例被认为是异步的。 HandleFileAsync 被调用,Console.WriteLine 调用被调用,然后我们等待 task 完成后再继续。
static async void ProcessDataAsync()
{
// Start the HandleFile method.
Task<int> task = HandleFileAsync("C:\\enable1.txt");
// Control returns here before HandleFileAsync returns.
// ... Prompt the user.
Console.WriteLine("Please wait patiently " +
"while I do something important.");
// Wait for the HandleFile task to complete.
// ... Display its results.
int x = await task;
Console.WriteLine("Count: " + x);
}
然而在下面的例子中,我们等待调用 Task.Run 来运行一个动作:
static async void Example()
{
// This method runs asynchronously.
int t = await Task.Run(() => Allocate());
Console.WriteLine("Compute: " + t);
}
那么,如果我们在这里等待 Task.Run 的完成,异步到底发生了什么?我认为一旦我们等待后续任务的执行完成,它就会变成一次阻塞调用,在这种情况下,它是在同一行上调用的。
我错过了什么?
【问题讨论】:
-
HandleFileAsync直到你最后await它才会被调用,所以你的 sn-ps 在异步功能方面基本相同。您只是将指针指向顶部的任务。但是,我相信您误解了async的作用。它只是在不阻塞主上下文线程(或 GUI 应用程序的 UI 线程)方面是异步的。代码仍将按顺序逐行运行 -HandleFileAsync不会与ProcessDataAsync中的其余代码并行运行。 -
@Rob:一点也不。在
ProcessDataAsync的第一行调用HandleFileAsync。 -
@bulletblue:我同意 Eric Lippert 的观点,即 dotnetperls 教程令人困惑且有些误导。我有 an async intro of my own 可以帮助你。
-
@StephenCleary 如果
Task<int> task = HandleFileAsync(...)行运行但从未等待任务,预期的行为是什么? HandleFileAsync 是否已执行,但我们只是没有得到结果?那么如果我们不关心结果而只关心执行,我们可以选择不等待吗? -
@Howiecamp:大多数时候“一劳永逸”是一个错误。你确定你不在乎结果吗?你不需要知道它是否失败? (异常将被放置在您的代码将忽略的任务上)。您不需要知道它何时完成,因此您的代码知道退出程序是安全的?
标签: c# async-await