当你使用async-await时,我在哪里定义Task以及我等待它的位置是否重要?

时间:2016-12-12 01:17:05

标签: c# .net asynchronous async-await

我正在查看示例方法

public async Task MyMethodAsync()
{
    Task<int> longRunningTask = LongRunningOperationAsync();
    // independent work which doesn't need the result of LongRunningOperationAsync can be done here

    //and now we call await on the task 
    int result = await longRunningTask;
    //use the result 
    Console.WriteLine(result);
}
来自How and When to use `async` and `await`

我对它是如何工作有疑问。

所以,让我们说一些&#34;独立工作&#34;它说我可以。

public async Task MyMethodAsync()
{
    Task<int> longRunningTask = LongRunningOperationAsync();
    int millionthPrimeNumber = GetMillionthPrimeNumber();
    int result = await longRunningTask;
    //use the result 
    Console.WriteLine(result % millionthPrimeNumber);
}

获得百万分之一的素数是独立的工作,所以我希望它是夹在Task<int> longRunningTask = LongRunningOperationAsync();int result = await longRunningTask;之间的东西

但是,我很好奇的是我是否可以写

public async Task MyMethodAsync()
{
    int result = await LongRunningOperationAsync();
    int millionthPrimeNumber = GetMillionthPrimeNumber();       
    //use the result 
    Console.WriteLine(result % millionthPrimeNumber);
}

这是否相同?或者Task<int> longRunningTask = LongRunningOperationAsync();int result = await longRunningTask;实际上是否作为标志,以便可以完成的独立工作是它们之间的任何内容?

2 个答案:

答案 0 :(得分:8)

很多人误解了这一点。

首先:await不会启动任务。调用任务返回方法启动任务。 Await不会导致同步的方法神奇地变为异步。

等待做什么?等待意味着此点之后的内容将在任务完成后的某个时间才会运行。而已。这就是它的含义。为实现这一目标,异步等待以完成任务。通过“异步等待”,我的意思是“返回呼叫者,以便在我们等待时可以完成更多工作”。

如果任务产生值,则await将从已完成的任务中提取值。这是完全一致的:如果后面的代码取决于任务的值,那么它还取决于正在完成的任务!

您应该等待代码等待以下代码取决于已完成等待的任务

  

这是否相同?

它们是等价的,因为它们最终都会产生相同的结果。它们表达不同的异步工作流程并不等同。

答案 1 :(得分:-1)

LongRunningOperationAsync方法应该包含一个I / O绑定的异步任务(例如文件系统或网络访问),以使程序从异步等待中受益。如果LongRunningOperationAsync仅包含受CPU限制的任务,那么一般来说,与方法不是async的情况相比,它没有什么不同。

这样想。如果你有这个代码:

int result = await LongRunningOperationAsync();

......想象一下这就是它。

int result;
await LongRunningOperationAsync();
//
// Here we leave MyMethodAsync and do other
// work in the meantime. When LongRunningOperationAsync
// finishes...
//

result = /* Result extracted from LongRunningOperationAsync */;

//
// Now we're back to MyMethodAsync and
// move on with the rest of the method using
// the value of `result`.
//

如果您的问题中LongRunningOperationAsync()longRunningTask替换,情况也是如此。