线程在“等待”某事时会发生什么

时间:2017-04-21 04:37:42

标签: c# async-await

System.out.println(node.at("/RESULTS/ATTACHMENTS/ATTACHMENT").isArray()); 方法asyncawaits当前正在运行的主题发生了什么变化?

我猜测在UI线程上消息循环恢复,并且在线程池线程上,线程被释放回线程池。但是如果线程是手动启动会发生什么?还有其他类型的线程吗?

3 个答案:

答案 0 :(得分:2)

这花了我很长时间才意识到,但async-await的这部分很简单,只需要调用堆栈即可。任何时候方法Task(假设它不是一个完成的任务或类似的东西)它返回给调用者。因为我们讨论的是代码放弃对线程的控制,这意味着这是代码堆栈顶部的最后一段代码。

如果我们在U​​I线程上运行,我们将返回消息循环。如果我们在线程池线程控制返回到线程池。手动创建的线程只运行void方法,如果它是awaits方法,则只能使用await,这意味着它甚至会在方法完成之前以第一个async void结束线程。

延续的工作方式相同。它会将它排在UI线程或线程池中,然后再次await或完成,再次放弃控制。

编辑:我已经完成了一些自定义任务调度程序的实验,你可以在那里应用完全相同的逻辑。等待任务时,它会控制。我使用的任务调度程序基于此single threaded task scheduler。在这种情况下,除草控制意味着任务调度程序开始处理队列中的下一个任务。同样重要的是要注意,除非使用awaits,否则将使用当前任务计划程序安排延续。

答案 1 :(得分:0)

请注意,没有手动线程这样的东西。它们都只是线程。像电子一样,没有两种类型的电子:)。

ThreadPool线程,您的线程,UI线程,COM线程等之间的区别在于线程是否具有消息循环,同步上下文。 如果线程有同步上下文,那么我们在它上面启动的所有内容都不会直接运行,但它都是从某个队列中作为委托启动的,当队列中没有任何内容时,线程正在等待。

因此,如果异步方法中的某些部分代码在具有同步上下文的此类线程上运行,则等待它存储上下文,除非使用此方法完成并等待下一个委托或消息执行。因此,当await完成并且未使用ConfigureAwait将下一个代码移动到线程池时,它会向同步上下文发送新委托,这是代码在等待处理之后的代码。

答案 2 :(得分:-1)

实际上,任何线程都可以同步运行异步方法,它会等到

=>

Stephen Cleary指出,这部分不正确:“等到异步方法完成”。措辞非常误导。所以也许这会好一点。

=>

完成所有同步执行的部分。可能正在等待已完成的任务,如Task.FromResult。此外,它可能是另一种异步方法,可以完全同步执行。

但是在等待某个地方等待在提供awaiter之前无法完成的操作的时刻,即使异步方法没有运行完成,t.RunSynchronously也会退出。

void ThreadWorker(object obj)
{
    var t = new Task<Task>(AsyncMethod);
    t.RunSynchronously();
    //in this case, it runs the AsyncMethod completely
    //and effectively waits for result
}

async Task AsyncMethod()
{
   await Something().ConfigureAwait(false);
   //everything from here runs on the ThreadPool
}