仅调用一个内衬async await方法的async await方法的用途是什么?它们跨越多少个线程?您最终会消耗多少CPU? 嗨,最近我看到了许多使用async和await关键字的方法。当仍然按如下所示应用它们时,我仍然不能全神贯注于它们的用法和基本行为以及它们的优势。当他们将CPU用于所有事物时,我也发现CPU出现问题(运行100%),我将thread.run视为某些情况下CPU利用率的元凶。
myController.cs
[HttpPost]
[ProducesResponseType(body)]
public async Task<IActionResult> Post([FromBody]Body body){
_MyClassService.sendMessage(body);
return Ok(body);
}
我的服务班
Myclass.cs
private async void sendMessage(){
await SendToProperChannel();
}
private async Task SendToProperChannel(){
await DoWorkInProperChannel();
}
private Task<int> DoWorkInProperChannel(){
await SomethingThatTakes5Seconds();
return 1+1;
}
据我所知。
我们正在使控制器请求异步,以便不阻塞主线程,从而允许在控制器级别获得更高的吞吐量。
我们还使所有函数异步,以不阻塞调用这些方法的上层线程。
我也理解,由于等待的人很多,每个人都返回一个任务,但是还有一个线程正在处理该工作,等待完成。
我仍然不清楚线程号,但是我相信我们会产生一个以上的线程来满足一个请求。
我的问题。
如果上部方法没有响应就无法继续使用,等待一根衬管有什么用?实际上,该API可以接收更多的吞吐量,但是从那里开始,所有内容都将实现某种程度的同步,并且还会产生更多的线程,只是为了在类中的方法之间跳转似乎并不健康。
如果我仅在一个班轮上等待,在此特定代码中,结果将与删除等待中的结果不同吗?
由于所有方法都不会阻塞,因此它们也将处理更多的吞吐量?
启动异步方法并等待同一方法内部的响应方式的语法如何。
示例:
private async Task<int> myAsyncWorkerMethod(){
var myNeededValue=methodThatINeed();
var mySecondValue=methodWithSecondValue();
await myNeededValue;
await mySecondValue;
return myNeededValue+mySecondValue;
}
异步并等待仅拥有一个线程池来处理所有下游调用有什么好处,您可以轻松地控制线程池的大小并轻松检测线程饥饿和队列深度? (我可能在这里使用了一些不适用的Java术语)
想法
在其他语言中,我看到了线程上下文更改的影响,如果您的CPU不够强大或者由于线程池大小而导致线程饥饿,那么.net不受控制的线程池不会具有相同的影响,而尽可能多地使用CPU?
如果您需要异步调用来返回对await语句的响应,则无需创建异步调用。仅当您需要对上述方法做一些工作时才需要进行异步处理吗?
即使您正在等待另一个类的方法结果,除非您不想阻塞主线程,也不要等待它。
预先感谢
答案 0 :(得分:2)
我将尝试一次回答您的观点和问题:
“我们正在使控制器请求异步,以便不阻塞主线程,从而允许在控制器级别接收更高的吞吐量。”
不,那是完全不正确的。打开适当的编译器异常,您会发现使用async
而不使用await
是浪费时间,这没有任何价值,并且会生成无用的IL代码。
“我也理解,由于等待的人很多,每个人都返回一个任务,但是还有一个线程正在处理正在等待完成的工作。”
“我仍然不清楚线程号,但是我相信我们会产生多个线程来满足一个请求。”
如上所述,这也是无效的。
如果上部方法如果没有响应就无法继续,那么等待一根衬管有什么用?
基本上没有,代码可能只是:
private async void sendMessage()
{
await DoWorkInProperChannel();
}
private Task<int> DoWorkInProperChannel()
{
// `await Thread.Sleep()` is not valid, `Sleep` returns `void`
await Task.Delay(1000);
return 1+1;
}
注意:上面的代码没有创建一个新线程;不在原始版本或我的版本中。
如果我仅在一个班轮上等待,在此特定代码中,结果将与删除等待中的结果不同吗?
一点也不,您需要return
生成的Task
才能使代码相同。当然,对于async void
方法来说,除了不能返回任何内容。
private async Task<int> myAsyncWorkerMethod() { var myNeededValue=methodThatINeed(); var mySecondValue=methodWithSecondValue(); await myNeededValue; await mySecondValue; return myNeededValue+mySecondValue; }
这被称为并行异步代码,与上一个示例无关。是否可以使用并行代码取决于您的工作。
在其他语言中,我看到了线程上下文更改的影响,如果您的CPU不够强大,或者由于线程池大小而导致线程饥饿,那么.net不受控制的线程池不会具有相同的影响,而尽可能多地使用CPU?
您发布的代码中没有一个上下文更改,因此这无关紧要。
即使您正在等待另一个类的方法结果,除非您不想阻塞主线程,也不要等待它。
您正在使用ASP.NET Core,没有主线程。