C# async/Wait whall立即返回

C# async/Wait whall立即返回,c#,.net,async-await,task-parallel-library,C#,.net,Async Await,Task Parallel Library,我有这个“简单”的测试代码。。。(不用担心类方法的奇怪用法…) 我正在努力掌握任务的复杂性。。。我想我对Task.Start()/Task.Result模式有一点了解(可能是因为它更像是“旧的”Thread.Start()?),但在我看来,一旦它掌握了一些东西(因此我加入了wait关键字)。。。然后一切又纠缠起来:-( 为什么我的代码在第一个任务完成后立即返回?为什么它不等待任务。WhenAll() 静态BigInteger因子(BigInteger因子) { 大整数阶乘=1; 对于(BigIn

我有这个“简单”的测试代码。。。(不用担心类方法的奇怪用法…)

我正在努力掌握
任务
的复杂性。。。我想我对
Task.Start()
/
Task.Result
模式有一点了解(可能是因为它更像是“旧的”
Thread.Start()
?),但在我看来,一旦它掌握了一些东西(因此我加入了
wait
关键字)。。。然后一切又纠缠起来:-(

为什么我的代码在第一个任务完成后立即返回?为什么它不等待
任务。WhenAll()

静态BigInteger因子(BigInteger因子)
{
大整数阶乘=1;
对于(BigInteger i=1;i阶乘(值));
}
公共异步任务getFactN()
{
BigInteger结果=等待计算同步(\n);
返回结果;
}
公共异步任务getFactN\u R()
{
BigInteger结果=等待CalculateFactAsync(\u n-\u r);
返回结果;
}
公共异步任务getFactR()
{
BigInteger结果=等待计算同步(\u r);
返回结果;
}
}
私有异步静态void TaskBasedChancesToWin_UseClass()
{
int n=69000;
int r=600;
列表任务=新列表();
ChancesToWin ctw=新ChancesToWin(n,r);
tasks.Add(ctw.getFactN());
tasks.Add(ctw.getFactN_R());
tasks.Add(ctw.getFactR());
//getFactR()返回其他两个任务中的第一个任务……然后代码退出!
BigInteger[]结果=等待任务。WhenAll(任务);
//我到不了这里!!!!
BigInteger机会=结果[0]/结果[1]*结果[2];
//Debug.WriteLine(机会);
}
静态void Main(字符串[]参数)
{
TaskBasedChancesToWin_UseClass();
}

异步方法同步运行,直到第一次等待时才将控制权返回给调用方法,通常返回代表异步操作其余部分的任务。
TaskBasedChancesToWin\u UseClass
不返回任务,因此调用方不能等待任务完成。这就是为什么不应使用
异步void
在事件处理程序之外

由于
Main
不会等待操作结束,因此应用程序会在操作有机会完成之前结束

您通常会使用
wait
等待,但由于您的
Main
不能是异步方法,因此您可以使用
wait
同步阻止从
TaskBasedChancesToWin\u UseClass
返回的任务:

async static Task TaskBasedChancesToWin_UseClass()
{
    // ...
}

static void Main()
{
    TaskBasedChancesToWin_UseClass().Wait();
}

好的,这对我来说似乎是有意义的……但是这样的话:当在“链”中时,你会停止将方法标记为async并使用await吗?换句话说,我不会将TaskBasedChancesToWin_UseClass方法标记为async,但我必须将其标记为async,否则我就不能等待任务(看起来像狗在追逐它的尾巴;-)@蜘蛛侠77最适合……你不会停止。异步在一路异步时效果最好。它最适合有上下文可返回的UI和web应用程序,但对于控制台应用程序来说效果不太好。在这种情况下,大多数人会同步阻止,但你也可以使用Stephen Cleary的
AsyncContext
之类的东西。在我的代码中,我无法模拟TaskBasedChancesToWin\u UseClass()方法的dd.Wait()!!!运算符“.”不能应用于“void”类型的操作数@spiderman77
TaskBasedChancesToWin\u UseClass
需要返回任务。您不应该组合
task.Factory.StartNew(
和async/await,此程序中没有这些bug,但是现在而不是以后打破“StartNew习惯”确实是个好主意。使用
Task.Run(
相反。好的,谢谢你的提示…我已经阅读了链接…但我必须更多地理解异步编程框架…不过简单地说,我理解,对于简单的情况,我可以简单地切换
Task.Factory.StartNew
Task.Run
而不需要太多的推理,对吗?是的,基本上,你只需要o
StartNew
如果您打算选择99.9%的时间不需要执行的非标准任务调度程序。
async static Task TaskBasedChancesToWin_UseClass()
{
    // ...
}

static void Main()
{
    TaskBasedChancesToWin_UseClass().Wait();
}