C# 异步等待概念

C# 异步等待概念,c#,multithreading,asynchronous,async-await,C#,Multithreading,Asynchronous,Async Await,我试图理解async和await的概念,但不能完全理解它的概念。据我所知,在Async Wait中,如果我们调用方法a,然后使用方法a中的Wait调用方法B,那么方法a的提醒将仅在方法B的工作完成后运行。我错过什么了吗?请纠正我 如果是这样的话,那么每次我们调用一个方法时,即使使用同步编程,方法a的提醒也会一直等到我们调用完方法B public void methodA(){ methodB(); Console.Writeline("MethodB has been called"); } p

我试图理解async和await的概念,但不能完全理解它的概念。据我所知,在Async Wait中,如果我们调用方法a,然后使用方法a中的Wait调用方法B,那么方法a的提醒将仅在方法B的工作完成后运行。我错过什么了吗?请纠正我

如果是这样的话,那么每次我们调用一个方法时,即使使用同步编程,方法a的提醒也会一直等到我们调用完方法B

public void methodA(){
methodB();
Console.Writeline("MethodB has been called");
}
public void methodB(){//do stuff}
现在使用异步等待:

public async Task methodA(){
await methodB();
Console.Writeline("MethodB has been called");
}
public async Task methodB(){//do stuff}
请介意我指出区别吗?我很难理解这个概念。通常,我会看到关于线程池和线程的帖子,但是没有一个清晰的概念,我不太明白

据我所知,在Async Wait中,如果我们调用方法a,然后使用方法a中的Wait调用方法B,那么方法a的提醒将仅在方法B的工作完成后运行

你说得有点对

让我们看一看使用async await的实际情况

假设您有一个Windows窗体程序。表单上有一个按钮。当用户按下此按钮时,程序将从internet获取一些内容。收到响应后,它会在标签中显示响应

显然,与其他操作(如添加内容、绘制文本框等)相比,在互联网上请求内容需要相当长的时间

如果不使用async await,则当程序等待服务器的响应时,表单将不会响应用户交互。那太糟糕了

现在让我们使用异步等待。我将使用您提供的代码:

public async Task methodA(){
    await methodB();
    Console.Writeline("MethodB has been called");
}
public async Task methodB(){//do stuff}

按下按钮时,将调用方法A<代码>方法B获取数据。当到达
wait
行时,
methodA
在调用
methodB
后立即返回。这样,程序执行不需要停留在
methodA
中,因此表单可以响应用户交互。创建状态机以记住执行在
methodA
中的位置。在
methodB
返回后,执行返回到
methodA
并执行其余部分。

async
wait
是让线程执行有用的工作,而不是无所事事地等待其他工作完成

如果我们编写代码创建一个新线程来做一些工作,然后立即阻塞当前线程以等待完成,那就是浪费。为什么我们不在当前线程上运行代码,让它完成有用的工作,并节省创建新线程的开销?1

那么,
等待
做什么呢?它允许当前方法比其所有工作完成时更快地返回到调用方。也就是说,我们指出当前运行的线程没有任何用途,但希望我们的调用者,或者我们的调用者调用者等,确实有一些其他可以在我们的线程上有效运行的东西

如果我们的方法在当前线程上有其他有用的功能,该怎么办?轻松-将可等待的创建与
await
本身分离,并在以下两者之间执行其他有用的工作:

public async Task methodA(){
  var mba = methodB();
  Console.Writeline("MethodB has been called");
  //Other useful work that doesn't depend on methodB
  var result = await mba
  //And now continue with the result from methodB
}
methodB
本身是如何实现其异步的,这完全是
methodB
的一个实现细节-我们所知道的是,它被安排在将来某个时间点完成返回的
任务
(这就是为什么其他语言在使用“任务”时使用“未来”或“承诺”等术语的原因)



1对于那些想知道为什么会有这一段的人来说,这是为了准确地反驳一个非常普遍的说法,即
wait
“创建一条新的线索”或类似的说法。

你做了什么研究?有大量资源试图解释async/await是如何工作的。另外,您知道什么是任务以及它是如何工作和使用的吗?首先,我建议您阅读以理解异步并不意味着“在另一个线程上运行”。然后意识到
async
await
实际上是释放当前线程去做一些有用的事情,而不是在某种程度上阻塞和等待异步的事情完成。让它看起来一样完全是async关键字的重点。如果没有它,您必须编写两个方法,一个让methodB运行,另一个在完成后运行。这可能会很尴尬,第二种方法无法访问第一种方法的任何局部变量。使用async/await,它看起来更自然。编译完成后,实际上您将得到两个方法。作为隐藏类的一部分,局部变量现在是该类的字段。所有这些都隐藏得很好,你只能通过像ildasm.EXE这样的反编译器来查看。这是一个很好的答案,非常有助于理解这个概念!因此,基本上,当我们使用wait时,我们会在wait methodB行运行后立即将控件返回给methodA(调用者),但是methodA的其余部分只有在methodB中的工作完成后才会运行?@manisharyal-不,我们在
wait
挂起时将线程返回给调用者
wait
具有局部效果,没有整行代码那么大。@manisharyal-而且,我们不能保证等待结束后,在特定上下文之外,我们会得到相同的线程来恢复我们的方法。因此,基本上,当我们使用wait时,我们会将控件返回给methodA(调用方)行之后立即等待methodB运行,但methodA的其余部分将仅在methodB中的工作完成后运行?1。然后MSDN说只有一个线程?methodB中的工作将在哪里运行?我在某个地方读到,等待使等待的方法像一个中断或smth,但完全不能得到它。2.在UI/UX应用程序中,当我们等待按钮上的任何行或UI/UX的任何控件时,我们的调用方是UI/UX吗?@manisharyal是的,只有一个线程。想象一下,电脑花了一些时间