C# 为什么在同一行上调用方法和等待它被认为是异步的?
为了更好地理解async/await,我正在查看上的示例,但以下内容让我感到困惑: 我理解为什么下面的示例被认为是异步的。调用HandleFileAsync,调用Console.WriteLine,然后等待任务完成后再继续C# 为什么在同一行上调用方法和等待它被认为是异步的?,c#,async-await,C#,Async Await,为了更好地理解async/await,我正在查看上的示例,但以下内容让我感到困惑: 我理解为什么下面的示例被认为是异步的。调用HandleFileAsync,调用Console.WriteLine,然后等待任务完成后再继续 static async void ProcessDataAsync() { // Start the HandleFile method. Task<int> task = HandleFileAsync("C:\\enable1.txt")
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的完成,那么异步运行到底发生了什么?我认为,当我们等待后续任务的执行完成时,它会变成一个阻塞调用,在本例中,它是在同一行上调用的
我错过了什么
我认为,当我们等待后续任务的执行完成时,它会变成一个阻塞调用,在本例中,它是在同一行上调用的。我错过了什么
你的信仰是错误的;这就是你所缺少的。“wait”的意思是“现在返回,在异步等待时运行其他程序,当结果可用时,返回此处。”
获取任务的结果做您认为等待做的事情。如果它所做的只是同步地获取任务的结果,我们就不必等待!它异步获取任务的结果
在我们讨论这个问题时,这个评论是错误的:
// Control returns here before HandleFileAsync returns.
这怎么可能呢HandleFileAsync返回了一个任务如果HandleFileAsync没有返回,控制如何在手头有任务的情况下到达该点?当然它回来了
这一评论具有误导性:
// Wait for the HandleFile task to complete.
这应该是异步等待任务完成。记住,异步等待的意思是“现在返回,运行更多的工作,当任务完成后,在这一点上继续,结果在手。”
如果我是你,我会找到更好的教程 什么是异步发生的?
考虑这一点:
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()代码>本身是异步发生的。
因此,如果您在(!done){}
程序在
Example()
完成之前退出。我希望这会有所帮助。
HandleFileAsync
在您等待它结束之前不会被调用,因此您的代码片段在异步功能方面基本相同。您只需将指针指向顶部的任务。但是,我相信您误解了async
的功能。它只是在不阻塞主上下文线程(或GUI应用程序的UI线程)方面是异步的。代码仍将按顺序运行,逐行-HandleFileAsync
不会与ProcessDataAsync
中的其余代码并行运行@Rob:根本不会HandleFileAsync
是在ProcessDataAsync
@bulletblue的第一行调用的:我同意Eric Lippert的观点,dotnetperls教程令人困惑,有些误导。我有一个可能对你有帮助的方法。@StephenCleary如果行Task Task=HandleFileAsync(…)
运行但任务从未等待,那么预期的行为是什么?是否执行了HandleFileAsync,但我们从未得到结果?因此,如果我们不关心结果,而只关心执行情况,我们可以选择不等待?@Howiecamp:大多数时候,“开火并忘记”是一个错误。你确定你不在乎结果吗?你不需要知道它是否失败了?(将在任务上放置异常,您的代码将忽略该异常)。您不需要知道它何时完成,所以您的代码知道退出程序是安全的?
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 ");
}
}
}