C# 在几乎相同的方法中异步/等待的不同行为
假设我有两个异步方法C# 在几乎相同的方法中异步/等待的不同行为,c#,.net,async-await,C#,.net,Async Await,假设我有两个异步方法 public async static Task RunAsync1() { await Task.Delay(2000); await Task.Delay(2000); } 及 然后我就这样用它 public static void M() { RunAsync1().GetAwaiter().GetResult(); RunAsync2().GetAwaiter().GetResult(); } 因此,RunAsync1将运行4秒,
public async static Task RunAsync1()
{
await Task.Delay(2000);
await Task.Delay(2000);
}
及
然后我就这样用它
public static void M()
{
RunAsync1().GetAwaiter().GetResult();
RunAsync2().GetAwaiter().GetResult();
}
因此,RunAsync1
将运行4秒,但RunAsync2
仅运行2秒有人能解释为什么吗?方法几乎相同。有什么区别 在第二种方法中,两个任务同时启动。它们将在2秒钟内完成(因为它们并行运行)。在第一个方法中,首先运行一个方法(2秒),等待它完成,然后启动第二个方法(2秒)。这里的关键点是任务。延迟(…)在你调用它的时候开始,而不是在你等待它的时候 要进一步澄清,第一种方法:
var t1 = Task.Delay(2000); // this task is running now
await t1; // returns 2 seconds later
var t2 = Task.Delay(2000); // this task is running now
await t2; // returns 2 more seconds later
第二种方法:
var t1 = Task.Delay(2000);
var t2 = Task.Delay(2000); // both are running now
await t1; // returns in about 2 seconds
await t2; // returns almost immediately, because t2 is already running for 2 seconds
在第一种情况下,你是说
public async static Task RunAsync1()
{
var t1 = Task.Delay(2000);
await t1;
var t2 = await Task.Delay(2000);
await t2;
}
这相当于
public async static Task RunAsync2()
{
var t1 = Task.Delay(2000);
var t2 = Task.Delay(2000);
await t1;
await t2;
}
换句话说,在第一种方法中,您正在进行顺序异步编程,第二种方法是并行异步编程。无论何时启动任务。它已经在您创建它时启动,而不是在您调用
wait
时启动
如果您创建了一个任务并将其放入一个变量中,那么当您等待它时,它可能已经完成了。你的第二个病例就是这样的<代码>等待只需确保它必须在继续之前完成。只需检查您的代码:
public async static Task RunAsync1()
{
await Task.Delay(2000); // Start a delay task, and WAIT for it to finish
await Task.Delay(2000); // Start a delay task, and WAIT for it to finish
}
因此,第二个等待任务延迟(2000)代码>在第一次调用完成后调用(2秒后)
而第二种方法,
public async static Task RunAsync2()
{
var t1 = Task.Delay(2000); // Start a task
var t2 = Task.Delay(2000); // Start a task
await t1; // Wait for task to finish
await t2; // Wait for task to finish
}
因此任务t1和t2同时运行
如果你把它改成
public async static Task RunAsync3()
{
var t1 = Task.Delay(2000); // Start a task
await t1; // Wait for task to finish
var t2 = Task.Delay(2000); // Start a task
await t2; // Wait for task to finish
}
您将获得与RunAsync1相同的结果。这不是变量的问题,而是何时何地使用wait
。如果你做了var t1=Task.Delay(2000)代码>然后<代码>等待t1代码>,你会得到相同的结果。第二个4。是否0:00等待第二次回调0:02
?@camden_kid:不,因为在第三步之后,您已经在0:02了(您已经在那里等待了2秒钟)。@hoffmale它的编写方式有点混乱。在0.02时,它并没有真正等待,因为它刚刚完成等待。@camden_kid:在步骤3中,您将等待任务1完成。这意味着要等到0:02,也就是任务1完成的时候。在步骤4中,您将等待任务2完成。碰巧,任务2正是在那个时刻完成的,所以没有太多的延迟。“等待任务完成”可能意味着“如果任务已经完成,立即返回”。@hoffmale很公平。谢谢。这是面试问题吗?这是演示异步代码如何工作的典型示例…@BlueRaja DannyPflughoeft不,它不是。它只是在存储库中使用的out代码的简单版本。你能告诉我你在哪里看到这段代码的演示吗?@MegaTron关于基本async
行为的讨论。
public async static Task RunAsync3()
{
var t1 = Task.Delay(2000); // Start a task
await t1; // Wait for task to finish
var t2 = Task.Delay(2000); // Start a task
await t2; // Wait for task to finish
}