当前位置: 首页 > 知识库问答 >
问题:

异步和等待关键字不会导致创建额外的线程?

江烨伟
2023-03-14

我很困惑。一个或多个任务怎么能在单个线程上并行运行?我对并行性的理解显然是错误的。

一些我无法理解的MSDN:

异步和等待关键字不会导致创建额外的线程。异步方法不需要多线程,因为异步方法不会在自己的线程上运行。该方法在当前同步上下文上运行,并且仅在方法处于活动状态时才在线程上使用时间。

.. 以及:

在启动任务和等待任务之间,您可以启动其他任务。其他任务隐式并行运行,但不会创建其他线程。

共有1个答案

巩俊远
2023-03-14

它们不是平行运行,而是轮流运行。当正在运行的任务的进度被阻止时,它将存储其状态并将控制权交给就绪任务。这是协作式多任务处理,而不是真正的并行。

线程按照示例原则操作。然而,我想强调以下几个关键区别。

首先,简单地说,因为异步不是OS线程:

  • 任务不会看到不同的线程ID
  • 当任务生成时,线程本地存储不会自动进行上下文切换

其次,行为上的差异:

  • async/wait使用协作多任务,Win32线程使用抢占。因此,所有阻塞操作都有必要使用async/wait模型显式地产生控制权。因此,您最终可以通过对未编写为屈服的函数进行阻塞调用来阻塞整个线程及其所有任务。
  • 任务不会在多重处理系统上并行执行。由于重入是受控制的,这使得保持数据结构一致变得更加容易。

正如Stephen在评论中指出的那样,如果使用多线程同步上下文,则可以在多个OS线程中同时执行(以及所有的复杂性和潜在的竞争条件)。但MSDN引用的是关于单线程上下文的情况。

最后,在使用相同设计范例的其他地方,通过研究以下内容,您可以了解许多有关异步的良好实践:

  • Win32光纤(使用与线程相同的调用样式,但具有协作性)
  • Win32重叠的I/O操作,Linuxaio
  • 协程
 类似资料:
  • 我遇到了一些使用c#的/关键字进行异步编程的最佳实践(我是c# 5.0的新手)。 给出的建议之一如下: 稳定性:了解您的同步上下文 ...一些同步上下文是不可重入的和单线程的。这意味着在给定时间只能在上下文中执行一个工作单元。这方面的一个例子是Windows UI线程或ASP.NET请求上下文。在这些单线程同步上下文中,很容易死锁。如果您从单线程上下文中生成一个任务,然后在上下文中等待该任务,您的

  • 我们有一个应用程序,它有一个包含通过数据库填充的成员的类。这里有一个典型的例子。 对于data1、data2、data3…dataN,我们有相同的模式。每个dataStructure都与另一个无关,它们只是在同一个类中。此数据是跨多个线程访问的。关于此模式的几个问题: 同步方法将使线程必须等待跨所有不同的布尔检查,对吗?哪个是不必要的? 数据结构需要同步吗?数据在应用程序的整个生命周期中都不会改变

  • 我最近阅读了有关async/await的文章,我感到困惑的是,我阅读的许多文章/帖子都指出,在使用async await(示例)时不会创建新线程。 我创建了一个简单的控制台应用程序来测试它 以下代码的输出是: 我想知道,如果没有创建其他线程,部分在哪里运行?如果它运行在同一个线程上,难道它不应该因为长的I/O请求而阻塞它吗?或者编译器足够聪明,如果它需要太长的时间,就可以将该操作移到另一个线程上,

  • 我一直试图理解C#中的Async/await和Task,但尽管看了youtube视频,阅读了文档,并参加了pluralsight课程,但一直失败得很厉害。 我希望有人能帮助回答这些稍微抽象的问题,帮助我的大脑摆脱困境。 1.为什么说async/await启用了一个“Asynchonrous”方法,而async关键字本身什么也不做,而await关键字添加了一个挂起点?添加挂起点不是强制方法同步操作,

  • 我使用blocking queue(LinkedBlockingQueue)在几个线程之间同步数据。请看下图。 主线程是一个生产者,它产生对象,然后将它们放入每个消费者的队列中(线程2-10)。需要强调的是,每个消费者都有自己的队列,每个产生的对象都将进入所有消费者的队列。 生产者的运行速度比使用者快得多,因此我们可以假设在使用者运行期间队列不应该为空。当任何使用者的队列达到其容量时,生产者将被阻

  • 在MSDN中,有这样一段话: 但我不知道加粗文字的确切含义,所以我似乎不需要更多的帮助。那么,为什么它在不使用线程的情况下变为异步呢? 来源:http://msdn.microsoft.com/en-us/library/hh191443.aspx