我正在查看http://www.dotnetperls.com/async上的示例,以便更好地了解异步/等待,但以下内容让我感到困惑:
我理解为什么以下示例被视为异步。调用 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 的调用,该 Task.Run 运行一个操作:
static async void Example()
{
// This method runs asynchronously.
int t = await Task.Run(() => Allocate());
Console.WriteLine("Compute: " + t);
}
那么,如果我们等待在这里完成Task.Run,那究竟是异步发生了什么?我们认为只要我们等待后续任务的执行完成就会成为阻塞调用,在这种情况下,在同一行上调用它。
我错过了什么?
答案 0 :(得分:9)
一旦我们等待后续任务的执行完成,我认为它会成为阻塞调用,在这种情况下,在同一行上调用它。我错过了什么?
你的信念是假的;这就是你所缺少的。 “await”意味着“现在返回,在我们异步等待时运行其他东西,当结果可用时,请回到这里。”
获取任务的结果会做您认为等待的事情。如果它只是同步获取任务的结果,我们就不必发明等待!它异步获取任务的结果。
虽然我们在这,但这个评论是错误的:
// Control returns here before HandleFileAsync returns.
怎么可能呢? HandleFileAsync返回了一个任务!如果HandleFileAsync没有返回,控件如何通过手头的任务来到达?当然它回来了。
这条评论具有误导性:
// Wait for the HandleFile task to complete.
应该异步等待以完成任务。通过异步等待,请记住,我们的意思是“现在返回,继续运行更多工作,当任务完成时,在此时恢复结果。”
如果我是你,我会找到更好的教程。
答案 1 :(得分:0)
究竟发生了什么异步? 考虑一下:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static volatile uint i;
static uint Test()
{
Thread.Sleep(1000);
i = 2; //uint.MaxValue;
while (i-- > 0) { }
return i;
}
static bool done;
static async void Example()
{
var t = await Task.Run(() => Test());
Console.WriteLine("result: " + t);
done = true;
}
static void Main(string[] args)
{
Example();
Console.WriteLine("wait: Control returns here before Example() returns ");
while (!done) { }
Console.WriteLine("done ");
}
}
}
Example();
本身是异步发生的。
所以如果你删除while (!done) { }
程序在Example()
完成之前退出
我希望这会有所帮助。