当all立即返回时Async /await
本文关键字:Async await 返回 all | 更新日期: 2023-09-27 18:18:58
我有这个"简单"的测试代码…(不要担心类方法的奇怪用法…)
我试图掌握Task<>
的复杂性…我想我对Task<>.Start()
/Task<>.Result
模式有一点了解(也许因为它更像"旧"的Thread.Start()
?),但一旦我抓住了一些东西(所以我把await
关键字扔进去)…然后一切又纠缠在一起:-(
为什么我的代码在第一个任务完成后立即返回?为什么不等待Task.WhenAll()
呢?
static BigInteger Factorial(BigInteger factor)
{
BigInteger factorial = 1;
for (BigInteger i = 1; i <= factor; i++)
{
factorial *= i;
}
return factorial;
}
private class ChancesToWin
{
private int _n, _r;
public ChancesToWin(int n, int r)
{
_n = n;
_r = r;
}
private Task<BigInteger> CalculateFactAsync(int value)
{
return Task.Factory.StartNew<BigInteger>(() => Factorial(value));
}
public async Task<BigInteger> getFactN()
{
BigInteger result = await CalculateFactAsync(_n);
return result;
}
public async Task<BigInteger> getFactN_R()
{
BigInteger result = await CalculateFactAsync(_n - _r);
return result;
}
public async Task<BigInteger> getFactR()
{
BigInteger result = await CalculateFactAsync(_r);
return result;
}
}
private async static void TaskBasedChancesToWin_UseClass()
{
int n = 69000;
int r = 600;
List<Task<BigInteger>> tasks = new List<Task<BigInteger>>();
ChancesToWin ctw = new ChancesToWin(n, r);
tasks.Add(ctw.getFactN());
tasks.Add(ctw.getFactN_R());
tasks.Add(ctw.getFactR());
// The getFactR() returns first of the other two tasks... and the code exit!
BigInteger[] results = await Task.WhenAll(tasks);
// I don't get here !!!!
BigInteger chances = results[0] / results[1] * results[2];
//Debug.WriteLine(chances);
}
static void Main(string[] args)
{
TaskBasedChancesToWin_UseClass();
}
异步方法同步运行,直到第一次等待时,它们将控制权返回给调用方法,通常返回一个代表异步操作其余部分的任务。TaskBasedChancesToWin_UseClass
不返回任务,所以调用者不能等待任务完成。这就是为什么你不应该在事件处理程序之外使用async void
。
由于Main
不会在操作完成之前等待应用程序结束。
您通常会等待await
,但由于Main
不能是异步方法,您可以在TaskBasedChancesToWin_UseClass
返回的任务上与Wait
同步阻塞:
async static Task TaskBasedChancesToWin_UseClass()
{
// ...
}
static void Main()
{
TaskBasedChancesToWin_UseClass().Wait();
}