我无法找到有关实际差异的任何信息。
所以我一直做到以下几点:
public async Task<int> DoSomethingAsync()
{
DoSomethingElse()
var result = await GetValueAsync();
var intValue = DoAnotherThing(result);
return intValue;
}
await
电话,然后直接使用它,但我最近看到一些帖子,人们正在做以下事情:
public async Task<int> DoSomethingAsync()
{
var task = GetValueAsync();
DoSomethingElse()
var result = await task;
var intValue = DoAnotherThing(result);
return intValue;
}
这是否意味着方法GetValueAsync
正在启动它的执行,然后我们等待它的结果呢?或者它是否意味着它同步执行但仍然await
能够执行?
答案 0 :(得分:4)
DoSomethingAsyncB
在这种情况下,DoSomethingAsyncA
将需要约5秒,其中GetValueAsync
将需要~10。但是,如果您的 00:00:10:0161446
00:00:05:0032000
返回的值计算是从其他地方开始的,那么就没有区别了。
<强>更新强> 我纠正了答案中的错误。这是我机器的输出:
.leftBarButtonItem
答案 1 :(得分:3)
在此
public async Task<int> DoSomethingAsync()
{
DoSomethingElse()
var result = await GetValueAsync();
var intValue = DoAnotherThing(result);
return intValue;
}
这意味着当您在不执行任何其他代码的情况下尽快等待GetValueAsync的结果时。
以下代码表示:
public async Task<int> DoSomethingAsync()
{
var task = GetValueAsync();
DoSomethingElse()
var result = await task;
var intValue = DoAnotherThing(result);
return intValue;
}
在等待GetValueAsync完成它时调用GetValueAsync并执行DoSomethingElse,然后在完成后继续执行DoAnotherThing
答案 2 :(得分:2)
人们常常认为async-await是由几个线程完成的。通常情况并非如此。除非您启动其他线程,否则所有代码都由同一个线程执行。检查当前线程的ThreadId将显示此信息。
在interview Eric Lippert explained async-await in a restaurant metaphor中。在中间某处搜索异步等待。
他解释说,如果一个厨师烤面包,他可以等到面包烤好或开始做其他事情,然后回来看看烤面包机是否完成烘烤。
在您的第二个DoSomethingAsync中也会发生同样的情况。将日期写入磁盘时,您的线程会将数据传递给磁盘写入程序。写入磁盘是一个相对缓慢的过程。线程不会等待写入日期,而是开始执行其他操作。当它完成其他操作后,线程将等待,直到磁盘写入完成写入磁盘。
这仅在磁盘写入可以在您的线程执行其他操作时继续写入时才有用。因此,您通常会在涉及硬件时看到异步函数,或者启动其他线程执行某些工作的进程。如果异步函数必须进行一些耗时的计算,那么使函数异步是没有用的,除非它启动另一个线程来进行计算。即使这样,这是否应该在异步函数内完成,或者调用者是否应该自由决定是让自己的线程进行计算还是启动不同的线程来执行此操作,这是值得怀疑的。
Another article that helped me to understand async-await by Stephen Cleary,这个网站的重要贡献者(再次感谢Stephen!)
答案 3 :(得分:1)
在第一个示例中,您不会在GetValueAsync()
返回结果之前执行代码。
在第二个 - 您将在var task = GetValueAsync();
和var result = await task;
之间执行代码 - 您将执行DoSomethingElse()
。
参见小例子:
public static Task<int> DoLongOperationAsync()
{
return Task.Run(() => { Thread.Sleep(5000); return 5; }); // 5 seconds
}
public static async Task TestMethod()
{
var result = await DoLongOperationAsync();
Console.WriteLine("Console");
Console.WriteLine(result);
}
public static async Task TestMethod2()
{
var result = DoLongOperationAsync();
Console.WriteLine("Console");
Console.WriteLine(await result);
}
static async DoSomething()
{
await TestMethod(); // here you see some text in console only after 5 seconds
await TestMethod2(); // here you see some text in console immediately and after 5 seconds you will see "5"
}
答案 4 :(得分:0)
您只需将Task结果的要求推迟到第一次以这种方式实际使用的语句,这意味着在执行到达该语句时,任务可能已经异步设置了它的结果。