我不明白使用 async-await 时如何将控制返回给调用者,因为当我执行此代码时,第一个线程在等待方法内调用任务时实际上被销毁,并且给出结果的线程执行所有剩余代码下面我也画了一个我认为执行的图,但似乎是错误的。
根据“将控制权返回给调用者”假设的工作流程:
![Results](https://i.stack.imgur.com/719iz.png)
Results
![enter image description here](https://i.stack.imgur.com/1uJ0y.png)
Main
public static string GetThreadId => Thread.CurrentThread.ManagedThreadId.ToString();
static async Task Main(string[] args) {
Console.WriteLine("From main before async call , Thread:" + GetThreadId);
string myresult = await TestAsyncSimple();
Console.WriteLine("From main after async call ,Thread:" + GetThreadId);
Console.WriteLine("ResultComputed:" + myresult+",Thread:"+GetThreadId);
Console.ReadKey();
}
异步任务
public static async Task<string> TestAsyncSimple() {
Console.WriteLine("From TestAsyncSimple before delay,Thread:" + GetThreadId);
string result=await Task.Factory.StartNew(() => {
Task.Delay(5000);
Console.WriteLine("From TestAsyncSimple inside Task,Thread:" + GetThreadId);
return "tadaa";
});
Console.WriteLine("From TestAsyncSimple after delay,Thread:" + GetThreadId);
return result;
}
谁能指出我正确的方向?还有什么原因导致新线程产生?总是在启动任务时?除了创建将执行剩余代码的新线程的任务之外,还有其他“触发器”吗?
async Main 方法转换为如下所示:
static void Main() {
RealMain().GetAwaiter().GetResult();
}
static async Task RealMain() {
// code from async Main
}
考虑到这一点,在“异步调用之前的主线程”点,您位于主应用程序线程(id 1)上。这是常规(非线程池)线程。您将在此线程上,直到
await Task.Factory.StartNew(...)
在此刻,StartNew
启动一个新任务,该任务将在线程池线程上运行,该线程是从池中创建或获取的(如果可用)。这是您示例中的线程 3。
当你到达await
- 控制权返回给调用者,本例中的调用者是线程 1。在重新等待之后,该线程会做什么?这里被屏蔽了:
RealMain().GetAwaiter().GetResult();
等待结果RealMain
.
现在线程3已经执行完毕但是TestAsyncSimple()
有更多代码要运行。如果在等待之前没有同步上下文(这里的情况 - 在控制台应用程序中)-等待之后的部分将在可用的线程池线程上执行。由于线程 3 已完成其任务的执行 - 它可用并且能够继续执行其余任务TestAsyncSimple()
and Main()
功能,它确实做到了。如上所述,线程 1 一直被阻塞 - 因此它无法处理任何延续(它很忙)。此外,它也不是线程池线程(但这与这里无关)。
当你到达之后Console.ReadKey
然后按下一个键——Main
任务最终完成,线程1(等待该任务完成)被解除阻塞,然后它从真正的Main函数返回并且进程被终止(仅在此时线程1被“销毁”)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)