究竟发生了什么,而不是等待关键字调用异步方法?

我有一个Web服务器,并有定期作业合并和发送记录(大量的请求日志)。

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

MergeAndPutRecords函数中,有代码合并记录,异步函数返回任务发送记录。 (显然它是亚马逊Kinesis Firehose的PutRecordBatchAsync。)

那么如果我没有等待关键字调用该函数会发生什么? 函数是否在分离的线程上运行? 这里说的不是。 那么什么是返回任务手段? 这里说的是没有等待关键字方式的异步方法

  • 在当前线程上启动异步方法。 忽略所有结果(包括例外)。
  • 那么我的定期作业和PutRecordBatchAsync是同时处理的吗? 我知道asynchronouse和并发是不同的。 但没有await关键字,它们在同一个线程中。 哪一个会先执行? 我很困惑......

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


    那么我的定期作业和PutRecordBatchAsync是同时处理的吗?

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

    虽然在内存并发中使用任务有益,但是IO调用一旦执行完全不需要线程,因为它依赖于硬件并发性,如果它使用线程,它所做的只是等待IO调用返回,因此浪费宝贵的系统资源并降低系统可扩展性

    你的情况是,基于IO的并发性,当你调用基于远程/网络的API时,异步等待在这里有什么帮助?

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

    如果你不使用async等待呢?

    意图为异步的调用将变为同步,并且会立即影响系统可伸缩性,因为线程现在被阻塞,对于长时间运行的IO操作来说甚至更糟。 你有没有看过JavaScript框架如何总是对服务器API进行AJAX(异步)调用,因此在没有阻止浏览器线程的情况下可以做更多的工作。

    一般来说,在内存处理中,您可以创建一定数量的任务,并使用Task.WaitAllParallel.ForEach处理集合,以进行异步处理,理想情况下建议不要在任何地方拥有Task.Run ,其首选必须为Async从入口点来看,就像在MVC中可能的情况一样,控制器可以是异步的。 多个呼叫使用Task.WhenAll代表任务分组在一起,然后等待。 即使您在代码中使用Task.Run ,然后使用async lambda来执行异步调用

    总结:

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


    如果一个方法返回一个Task ,最好的做法是在某个时候观察该Task的结果。 它可能是声明的返回值,也可能是一个例外。 如果你想在你的方法继续之前观察那个任务,那么await就是建议。

    在这种情况下,您应该可以观察PutRecordBatchAsync返回的Task的结果。 你会想知道电话是否因任何原因失败,因为这可能表明你的记录没有被存储!

    在您给出的示例代码中,您会发现在前一个调用完成之前,您将对MergeAndPutRecords进行后续调用。 你确定这是有意的吗?

    链接地址: http://www.djcxy.com/p/79323.html

    上一篇: What exactly happens call async method without await keyword?

    下一篇: Trouble understanding async and await