C# 等待呼叫不';如果等待的任务中有一个长时间运行的CPU操作,则不要向调用者返回调用
wait Subtask()调用不应该立即将控件返回主函数吗? 当我运行这个程序时,它实际上会等待长时间运行的double for循环(子任务内部)完成,并且只在调用下面的Task.Delay()后返回main。 为什么调用wait Subtask()后它不立即返回C# 等待呼叫不';如果等待的任务中有一个长时间运行的CPU操作,则不要向调用者返回调用,c#,async-await,task,C#,Async Await,Task,wait Subtask()调用不应该立即将控件返回主函数吗? 当我运行这个程序时,它实际上会等待长时间运行的double for循环(子任务内部)完成,并且只在调用下面的Task.Delay()后返回main。 为什么调用wait Subtask()后它不立即返回 static void Main(字符串[]args) { WriteLine(“Main()线程ID:+Thread.CurrentThread.ManagedThreadId”); 超级任务(); Console.Read();
static void Main(字符串[]args)
{
WriteLine(“Main()线程ID:+Thread.CurrentThread.ManagedThreadId”);
超级任务();
Console.Read();
}
静态异步任务超级任务()
{
Console.WriteLine(“超级任务线程ID:+Thread.CurrentThread.ManagedThreadId”);
等待子任务();
}
静态异步任务子任务()
{
WriteLine(“等待前子任务的线程ID为:”+Thread.CurrentThread.ManagedThreadId);
var x=0;
对于(变量i=0;i<25000;i++)
{
对于(var j=0;j<250000;j++)
{
x-=i;
}
}
等待任务。延迟(10000);
WriteLine(“子任务的线程ID为:”+Thread.CurrentThread.ManagedThreadId);
}
您可能遇到了某种种族问题,尽管控制台应该对此免疫。检查此问题的标记答案:正如我在中所解释的,async
关键字不会启动新线程或类似的疯狂操作。每个async
方法都开始同步执行。这是经过设计的,Subtask()
方法在到达await
语句并启动await Delay
操作后立即返回。我再解释一下这是故意的。wait作为一个同步调用启动,直到它在调用链中找到另一个wait,这实际上导致了线程的创建。在您的场景中,这是直到调用Task.Delay,它实际上创建了一个线程(在本例中,它什么也不做,只等待10秒),但调用现在可以返回到调用方。在另一种情况下,如果您将循环代码放入Task.Run,那么控件将立即返回调用方您没有从代码中观察到任何编译器警告?只是建议我在Main方法中等待对SuperTask()的调用在这种情况下,SuperTask()不应该吗一旦看到行“wait SubTask()”,就将控件返回到Main?为什么在将控件释放到Main之前,它要在子任务内部等待wait?@Abhi:Becausewait Subtask()代码>与任务子任务=子任务()相同;等待子任务代码>。
static void Main(string[] args)
{
Console.WriteLine("Main() threadId: " + Thread.CurrentThread.ManagedThreadId);
SuperTask();
Console.Read();
}
static async Task SuperTask()
{
Console.WriteLine("SuperTask threadId: " + Thread.CurrentThread.ManagedThreadId);
await SubTask();
}
static async Task SubTask()
{
Console.WriteLine("ThreadId for SubTask before await is: " + Thread.CurrentThread.ManagedThreadId);
var x = 0;
for (var i = 0; i < 25000; i++)
{
for (var j = 0; j < 250000; j++)
{
x -= i;
}
}
await Task.Delay(10000);
Console.WriteLine("ThreadId for SubTask is: " + Thread.CurrentThread.ManagedThreadId);
}