Ber*_*ian 1 c# multithreading async-await
我不明白在使用async-await时控件是如何返回给调用者的,因为当我执行这段代码时,第一个线程在等待方法中调用task时几乎被破坏,并且给出结果的线程执行所有剩余的代码.我还画了一幅关于我如何看待执行的图表,但似乎是错的.
根据"将控制权返回给来电者"假定的工作流程:
结果
主要
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();
}
Run Code Online (Sandbox Code Playgroud)
异步任务
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;
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以指向正确的方向吗?还有什么原因导致新线程产生?总是在启动任务时?除了创建新线程以执行剩余代码的任务之外还有其他"触发器"吗?
async Main方法转换为如下所示:
static void Main() {
RealMain().GetAwaiter().GetResult();
}
static async Task RealMain() {
// code from async Main
}
Run Code Online (Sandbox Code Playgroud)
考虑到这一点,在"从主要的异步调用之前"点,你在主应用程序线程(id 1).这是常规(非线程池)线程.你会在这个线程上直到
await Task.Factory.StartNew(...)
Run Code Online (Sandbox Code Playgroud)
此时,StartNew启动一个将在线程池线程上运行的新任务,该线程池已创建或从池中获取(如果已经可用).这是您示例中的第3个主题.
当你到达时await- 控制权返回给调用者,在这种情况下,调用者是线程1.调查await后这个线程做了什么?它被阻止在这里:
RealMain().GetAwaiter().GetResult();
Run Code Online (Sandbox Code Playgroud)
等待结果RealMain.
现在线程3已经完成执行但是TestAsyncSimple()有更多的代码要运行.如果在await之前没有同步上下文(这里的情况 - 在控制台应用程序中) - await之后的部分将在可用的线程池线程上执行.由于线程3已完成其任务的执行 - 它可用并且能够继续执行其余的TestAsyncSimple()和Main()功能.如上所述,线程1一直被阻止 - 因此它不能处理任何延续(它很忙).另外它也不是线程池线程(但这不是相关的).
到达Console.ReadKey并按下一个键 - Main任务最终完成后,线程1(等待此任务完成)被解除阻塞,然后它从真正的Main函数返回并且进程终止(仅此时线程1被"销毁").