简体   繁体   English

除非首先将 Task 声明为变量,否则异步方法会同步运行?

[英]Async method runs synchronously unless Task is first declared as variable?

I am trying to wrap my head around the proper way to call asynchronous tasks.我试图用正确的方法来调用异步任务。 Consider the following code:考虑以下代码:

var stopWatch = new Stopwatch();

// TEST 1 AWAITS THE ASYNC TASKS DIRECTLY
stopWatch.Start();
Console.WriteLine($"Test 1 Begin: {stopWatch.ElapsedMilliseconds}");
await Task1(stopWatch);
await Task2(stopWatch);
Console.WriteLine($"Test 1 End: {stopWatch.ElapsedMilliseconds}");


Console.WriteLine();
Console.WriteLine();
stopWatch.Restart();


// TEST 2 CREATES A LOCAL VARIABLE OF THE TASK THEN AWAITS THE LOCAL VARIABLE
Console.WriteLine($"Test 2 Begin: {stopWatch.ElapsedMilliseconds}");
var task1 = Task1(stopWatch);
var task2 = Task2(stopWatch);
await task1;
await task2;
Console.WriteLine($"Test 2 End: {stopWatch.ElapsedMilliseconds}");


async Task Task1(Stopwatch stopWatch)
{
    Console.WriteLine($"Task 1 Start: {stopWatch.ElapsedMilliseconds}");
    await Task.Delay(2000);
    Console.WriteLine($"Task 1 End: {stopWatch.ElapsedMilliseconds}");
}

async Task Task2(Stopwatch stopWatch)
{
    Console.WriteLine($"Task 2 Start: {stopWatch.ElapsedMilliseconds}");
    await Task.Delay(2000);
    Console.WriteLine($"Task 2 End: {stopWatch.ElapsedMilliseconds}");
}

TEST 1 total time: 4 seconds测试1总时间:4秒

TEST 2 total time: 2 seconds TEST 2总时间:2秒

Why is TEST 1 running synchronously and TEST 2 is running asynchronously?为什么 TEST 1 同步运行而 TEST 2 异步运行?

In Test 1 you await the first Task which runs to completion then you start the second Task.在测试 1 中,您等待第一个任务运行完成,然后启动第二个任务。

In Test 2 you start both Tasks so when the first has run to completion the second is also either complete or really close to it so await takes no time or very little time.在测试 2 中,您启动两个任务,因此当第一个任务运行完成时,第二个任务也已完成或非常接近,因此await不需要时间或花费很少的时间。

Nothing is synchronous, the tasks are still executing asynchronously.没有什么是同步的,任务仍在异步执行。

You need to think about what is actually happening in two cases.您需要考虑两种情况下实际发生的情况。 I the first case If you look at the output that the log is我第一种情况如果您查看日志的输出

Task 1 Start:...
Task 2 Start:...
Task 1 End
Task 2 End

This is because the code in your method will run until the first await operator, then it will return a Task, then the second method runs and again return a task.这是因为您的方法中的代码将一直运行到第一个 await 运算符,然后它将返回一个 Task,然后第二个方法运行并再次返回一个任务。 When you do await on a task it's similar to calling task.ContinueWith(...) method on it.当您等待任务时,它类似于调用 task.ContinueWith(...) 方法。 And because the two timers have started almost at the same time the timer will finish at the same time with the Task will be completed at the second call.并且由于两个计时器几乎同时启动,计时器将同时完成,任务将在第二次调用时完成。 So the total is ~2s.所以总数是~2s。 On the second call the output is在第二次调用时,输出是

Task 1 Start:...
Task 1 End
Task 2 Start:...
Task 2 End

That is because it needed to await the first task before it started the second second task.那是因为它需要在开始第二个第二个任务之前等待第一个任务。 Try reading this for more information.尝试阅读本文以获取更多信息。 https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/ https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM