是否等待完全阻止线程?

时间:2016-01-10 13:05:01

标签: c# .net multithreading asynchronous

当我们在代码中使用await时,通常awaiters捕获上下文并在等待的任务成功完成时将其用作回调。但是,由于await通常是No.Op(No Operation),它是否会使得底层线程在被等待任务的执行完成之前不可重用?

例如

public async Task MethodAAsync()
{
     // Execute some logic
     var test = await MethodB();
    // Execute Remaining logic.
}

在这里,由于我需要将结果继续进行,我需要等待。但是,既然我们正在等待,它是否会阻止底层线程导致线程不被用于执行任何任务?

3 个答案:

答案 0 :(得分:4)

  

但是,由于等待通常是No.Op(无操作),它是否成功   底层线程在执行等待任务之前不可重用   完成?

我不确定您从何处获取此信息,但await 肯定不是No-Op 。例如,在await上调用Task会调用Task.GetAwaiter的逻辑调用,其中TaskAwaiter必须实现INotifyCompletionICriticalNotifyCompletion interface,告诉编译器如何调用continuation(第一个await之后的所有内容)。

async-await的完整结构将您的调用转换为状态机,这样当状态机命中第一个await时,它将首先检查被调用的方法是否已完成,以及是否不会注册延续并从该方法调用返回。之后,一旦该方法完成,它将重新进入状态机以完成该方法。从逻辑上讲,这是await被击中后的线条。

  

但是,既然我们正在等待,它是否会阻止底层线程   结果线程没有被用来执行任何任务?

不,创建一个仅阻止调用线程的整个机制将毫无用处。 async-await允许您实际将调用线程返回给调用者,这允许他继续在同一个线程上执行,而运行时负责排队并调用完成。

答案 1 :(得分:3)

简而言之,不,它不会阻止你的线程。

更多信息:http://blog.stephencleary.com/2013/11/there-is-no-thread.html

答案 2 :(得分:-1)

该线程具有任务的本地队列。一旦它到达await,它将从它的队列中获取另一个任务(假设它的所有方法都是awaited)。如果队列为空,它将尝试从全局队列中获取任务,如果它也是空的 - 线程将尝试从另一个线程自己的本地队列获取任务。在一个简单的程序中,所有线程都可以从任务中获得" - 线程将保持空闲状态,直到其中一个任务返回。