简体   繁体   English

带/不带异步和等待的任务

[英]Task with/wihout async and await

I have this method :我有这个方法:

public static Task TaskMethod ()
{
    Task.Delay(30000); 
    return Task.Run(() => Console.WriteLine("From Task") ); 
}

If I call it like this:如果我这样称呼它:

public static async Task Main()
{
    Console.WriteLine("before calling the task");
    TaskMethod();
    Console.WriteLine("after calling the task"); 
    Console.ReadLine(); 
}

I have this output:我有这个输出:

before calling the task在调用任务之前
after calling the task调用任务后
From Task从任务

But if I call this:但如果我这样称呼:

public static async Task Main()
{
    Console.WriteLine("before calling the task");
    await TaskMethod();
    Console.WriteLine("after calling the task"); 
    Console.ReadLine(); 
}

I have this result:我有这个结果:

before calling the task在调用任务之前
From Task从任务
after calling the task调用任务后

Is this behavior normal?这种行为正常吗? Why I'm allowed to await the task without using async?为什么我可以在不使用异步的情况下等待任务?
What I'm missing?我缺少什么?

I will try to explain.我会尽力解释。

Case: You don't await the returning value then it will execute the line and proceed to execute the next.案例:您不等待返回值,然后它将执行该行并继续执行下一个。

Console.WriteLine("before calling the task"); // execute 1
TaskMethod();                                 // execute 2
Console.WriteLine("after calling the task");  // execute 3

The confusing output that you get is because your machine needs less time to execute the 3rd command than it needs to execute the 2nd (creating a task, starting it, printint to console).您得到的令人困惑的输出是因为您的机器执行第三条命令所需的时间少于执行第二条命令所需的时间(创建任务、启动它、打印到控制台)。 The 2nd call runs in parallel to the 3rd.第二次调用与第三次调用并行运行。 This is also due to the fact that the Task.Delay call is not waiting because you don't await it and the same principle applies there as it applies here.这也是因为Task.Delay调用没有等待,因为您没有await它,同样的原则适用于此处,适用于此处。

To give you a little examplary proof here is a code that introduces a slight synchronous delay between the 2nd and 3rd call:为了给您一些示例性证明,这里有一段代码,在第二次和第三次调用之间引入了轻微的同步延迟:

public static async Task Main()
{
    Console.WriteLine("before calling the task");
    TaskMethod();
    Thread.Sleep(50);
    Console.WriteLine("after calling the task");
    //Console.ReadLine();
}

This gives the starting of the 2nd call a little more time to be executed before the 3rd step is performed.这使得第二次调用的开始在执行第三步之前有更多的时间来执行。 And you get the output:你得到输出:

before calling the task在调用任务之前
From Task从任务
after calling the task调用任务后

Now to the fact that the method Main runs actually synchronous on the main thread.现在, Main方法实际上是在主线程上同步运行的。 This screenshot from LINQPad shows the message that Visual Studio would also display:来自 LINQPad 的此屏幕截图显示了 Visual Studio 还将显示的消息:

在此处输入图片说明

It tells you that the main method will block the main thread until it is finished.它告诉你 main 方法将阻塞主线程直到它完成。 Because there is no await in it.因为里面没有等待。

Whereas the TaskMethod inside the Main will run asynchronously and in parallel to the next commands which runs on the main thread!MainTaskMethod将异步运行并与在主线程上运行的下一个命令并行运行! Whoever is faster gets to print it's message.谁更快就可以打印它的消息。

Why the Task.Delay call is useless without await ?=!为什么Task.Delay调用在没有 await 的情况下毫无用处?=!

The Delay method returns a task which is started, actually quite exactly like your TaskMethod . Delay方法返回一个已启动的任务,实际上与您的TaskMethod非常相似。 If you don't await this delay task, it will run in parallel.如果您不等待此延迟任务,它将并行运行。 Thus obliterating the entire effect of a delay.从而消除了延迟的整个影响。 You should actually notice that your console prints all 3 lines at the same time, there is no delay between the second and third line!您实际上应该注意到您的控制台同时打印所有 3 行,第二行和第三行之间没有延迟!

Why I'm allowed to await the task without using async?为什么我可以在不使用异步的情况下等待任务?

Because the necessity of async refers always to the method inside which the await call is made and not the method that is awaited!因为async的必要性始终是指进行await调用的方法,而不是await的方法! This can be seen in the fact that you cannot simply add an await to the Task.Delay call because the TaskMethod is not declared as async !这可以从以下事实中看出:您不能简单地向Task.Delay调用添加 await,因为TaskMethod未声明为async

在此处输入图片说明

(Hopefully) last EDIT: (希望)最后一次编辑:

The await operator needs a Task whose execution it can await, and because your TaskMethod returns a Task the operator can be applied. await运算符需要一个可以等待其执行的Task ,并且因为您的TaskMethod返回一个Task ,所以可以应用该运算符。 You can make nice things with it if you take the returning task.如果你接回任务,你可以用它来做点好事。 You can then decide when to wait for the end of it's execution!:然后,您可以决定何时等待执行结束!:

public static async Task Main()
{
    Console.WriteLine("before calling the task");
    Task taskToBeAwaitedMuchLater = TaskMethod();
    Console.WriteLine("after calling the task");
    await taskToBeAwaitedMuchLater;
    Console.WriteLine("after awaiting the result of the task");
    //Console.ReadLine();
}

Output:输出:

before calling the task在调用任务之前
after calling the task调用任务后
From Task从任务
after awaiting the result of the task等待任务结果后

I have this method :我有这个方法:

public static Task TaskMethod ()
{
    Task.Delay(30000); 
    return Task.Run(() => Console.WriteLine("From Task") ); 
}

If I call it like this:如果我这样称呼它:

public static async Task Main()
{
    Console.WriteLine("before calling the task");
    TaskMethod();
    Console.WriteLine("after calling the task"); 
    Console.ReadLine(); 
}

I have this output:我有这个输出:

before calling the task在调用任务之前
after calling the task调用任务后
From Task从任务

But if I call this:但如果我这样称呼:

public static async Task Main()
{
    Console.WriteLine("before calling the task");
    await TaskMethod();
    Console.WriteLine("after calling the task"); 
    Console.ReadLine(); 
}

I have this result:我有这个结果:

before calling the task在调用任务之前
From Task从任务
after calling the task调用任务后

Is this behavior normal?这种行为正常吗? Why I'm allowed to await the task without using async?为什么我可以在不使用异步的情况下等待任务?
What I'm missing?我缺少什么?

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

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