gpt4 book ai didi

c# - 当您调用不带 await 关键字的异步方法时究竟会发生什么?

转载 作者:太空狗 更新时间:2023-10-29 17:51:31 24 4
gpt4 key购买 nike

我有一个网络服务器,有一个定期的作业合并和发送记录(很多请求日志)。

Task.Run(() =>
{
while (true)
{
try
{
MergeAndPutRecords();
}
catch (Exception ex)
{
Logger.Error(ex);
}
}
});

MergeAndPutRecords函数中,有代码合并记录和async函数返回Task发送记录。 (实际上是 Amazon Kinesis Firehose 的 PutRecordBatchAsync 。)

那么如果我在没有 await 关键字的情况下调用该函数会发生什么?函数是否在单独的线程上运行? Here says it is not .那么什么是return Task Means呢? Here说没有 await 关键字的异步方法意味着

  1. Starts the asynchronous method on the current thread. Ignores all results (including exceptions).

那我的periodic job和PutRecordBatchAsync是并发处理的吗?我知道异步和并发是不同的。但是没有 await 关键字,它们在同一个线程中。哪个先被处死?我很困惑...

会有大量记录需要实时合并和发送。所以我认为它必须并发执行..

最佳答案

Then my periodic job and PutRecordBatchAsync are processed concurrently?

使用任务 API,您可以确保它们并发执行(使用线程池),但您需要了解内存并发操作与基于 IO 的并发之间的区别。

虽然在内存中并发确实有利于使用任务,但一旦执行 IO 调用就根本不需要线程,因为它依赖于硬件并发,如果它曾经使用线程,它会等待 IO 调用从而浪费了宝贵的系统资源,降低了系统的可扩展性

You case is that IO based concurrency, as you call a remote / network based API, how does async-await helps here ?

是的,异步操作会释放线程上下文,在windows上它会使用IO完成端口(排队机制)来执行异步调用,而调用线程用于调度其他类似的调用,它只需要线程上下文在为响应提供服务的 IO 调用返回时,如果它不是 UI 调用,则使用 ConfigureAwait(false),以便可以使用任何线程上下文来传递响应。

What if you don't use await with async ?

本来应该是异步的调用变成了同步的,并且会立即影响系统的可伸缩性,因为线程现在被阻塞了,对于长时间运行的 IO 操作来说更糟。您是否看到 JavaScript 框架如何始终对服务器 API 进行 AJAX(异步)调用,因此可以在不阻塞浏览器线程的情况下完成更多工作。

一般来说,对于内存处理,您会创建一定数量的任务,并使用 Task.WaitAllParallel.ForEach 来处理它们,对于异步处理,理想情况下建议不要在任何地方使用 Task.Run,最好从入口点开始 Async,就像在 MVC 的情况下一样, Controller 可以是异步的。使用 Task.WhenAll 代表 Task 将多个调用组合在一起,然后等待。即使您在代码中使用 Task.Run,然后使用 async lambda 执行异步调用

Summary :

必须使用 await 进行异步调用,否则它们的 async 关键字在该上下文中是无用的,是的 await 将等待 IO在继续执行之前调用返回,尽管进程中没有线程被阻塞

关于c# - 当您调用不带 await 关键字的异步方法时究竟会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47938520/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com