我有两个问题。我对 C# 中的异步编程有很好的理解,但仍然存在一些问题。
1) 现在我将描述一个 asp.net 应用程序中的经典情况。例如,您在控制器中有一个操作,它返回一些数据(例如 user'a)。在这种情况下,您在控制器中编写对服务的调用,该服务将返回 user'a 给您,自然,当您调用此服务时,您使用 await。事实证明,当存储库(由服务调用)访问数据库时,当前线程将被释放并返回到控制器,它也不需要做任何事情。这有什么意义?好吧,我释放了线程,然后直到我得到数据,我的调用方法不能继续工作,那为什么还要在这里等待呢?也许在 asp.net 中用于处理我的应用程序中的请求的线程数量有限?我在一堆办公室的所有项目中都观察到这一点,也许我不明白什么?
2)我们经常在访问数据库(对数据库的请求在操作系统中处理它的地方),对计算机文件(也是应用程序之外的操作,即在操作系统中)之前使用await,有时会创建一个线程已经在应用程序中。在所有这些情况下,由于等待,我的主线程空闲时代码正在执行某些操作。最后,我不明白为什么大家建议在Task.Delay之前写await。
我们很清楚,await 不会创建线程,只是简单地根据 await 的次数将方法拆分为多个片段,并在任务完成后作为回调继续执行每个片段,而且它还把 Task 变成了 T(就像我们使用 ContinueWith 一样)。那么谁来执行Task.Delay呢?也许是当前线程(称为 Task.Delay),但是为什么要等待呢?谁执行 Task.Delay?
3)在asp.net应用中,有ConfigureAwait这样的方法,也有HttpContext这样的东西。ConfigureAwait(false) 是否表示 await 之后的第二部分可以在任何上下文中执行?以及如何理解这一点,我会有不同的httpcontext还是什么?我还听说在 asp.net core 中它的工作方式有所不同,那里有什么不同?
4)最后一个问题。异步就像一段代码正在某处执行或等待某事,而无论主线程在等待什么,我们都会释放它以便它可以做其他事情。并且当延续所需的一段代码完成其操作时,我们会自动(关键字自动)返回到它。我是否正确理解了所有内容?
不正确,当前线程将去处理另一个请求。这是异步的技巧之一——当一个任务在等待外围设备(数据库、文件系统或网络)时,线程可以处理另一个任务。
是的
不一定有空,这个时候他可以做点别的工作。
在那之前你想写什么?任务刚刚
Task.Delay()开始,如果你不等待它,那么这个任务没有意义。await它本身什么也不做,它是一个关键字,它与 async 一起将源代码重新制作为最终的自动。是的。
ConfigureAwait(false)意味着您不关心延续将在什么上下文中执行。我不建议继续尝试调用任何上下文相关的事物,例如HttpContext我记得有一个错误,与 asp.net 中的死锁有关(我可能找不到链接),当调用
myTask.Result可能阻塞流时。这是在 asp.net core 中修复的,似乎在 asp.net 中没有修复。但我不使用网络,所以我可能是错的。多线程与异步编程