繁体   English   中英

使用async和await的最佳性能

[英]Best performance using async and await

我有一个核心机器,我想使用async和await来提高我的代码性能。 代码有两个主要部分。 第一个IO操作。 (从azure服务总线队列读取多个sessionId),第二个,处理数据--CPU重。 我已经在异步方法中包装了DequeueAsync方法,该方法返回一个Task:

private async Task<SomeReturnValue> AcceptFromQueueAsync(){
  try{ 
       SomeReturnValue result = await DequeueAsync.configureAwait(false);
       return SomeReturnValue;  
  }
  catch{
   //logging and stuff
  }

CPU重载方法是同步:DoSyncWork()由于第二部分CPU很重,我不想使用并行性(实际上不能......)CPU部分只能在IO部分完成时启动。 鉴于以上是以下实现1 cpu机器的方式?

private void AcceptAndProcessWrapper(){
    //Count is some cosnt defined outside the method
    _acceptTasks = new List<Task<SomeReturnValue>>();
     for (var i = 0; i < Count; i++)
     {
                    _acceptTasks.Add(AcceptFromQueueAsync());
      }
      //The use of list is for convince in processing  
      Task.WaitAll(_acceptTasks.ToArray());
      //The CPU part 
       Task.Run(DoSyncWork).Wait();
 }

我知道我可能没有使用Task.Run()作为同步部分,但我想允许在多个核心上实现功能(通过使用Task.Run()启动几个任务并将它们保存在一个数组中)请问上面的实现。 (多次调用返回任务的异步方法)可以提高性能? 或者我应该为每个异步调用启动一个新任务,例如Task.Run(AcceptFromQueueAsync)?

您拥有的代码确实会并行执行异步出列。 它将立即启动所有异步任务,然后等待它们全部完成以继续。

添加对Task.Run的额外调用Task.Run 在另一个线程中启动异步任务只是为没有附加值而增加了额外的开销。 Task.Run应该用于在另一个线程中运行CPU绑定工作 ,而不是在另一个线程中的异步工作。

说到使用Task的性能(如果将来使用它与DoSyncWork一起DoSyncWork ),你应该记住Task.Run默认使用ThreadPool,但是线程池中的线程预计会做一些快速和小的工作。 如果任务确实是一些“重”的,你应该考虑在新创建的线程中运行它们,这可能也会强制使用以下内容:

new Task(() => { }, TaskCreationOptions.LongRunning);

编辑:

在下面的一些谈话中,我想要更清楚一些事情。

目前, Task.Run(DoSyncWork).Wait(); 真的没有任何意义(甚至更多,可能需要额外的时间在另一个线程上运行任务(即使是从ThreadPool的线程),但如果你想在将来使用多个核心,你显然应该将该任务移动到另一个线程到运行(如果它真的是CPU重,那么考虑将任务作为“ LongRunning ”运行)(如果它当然需要你的应用程序(不确定你的应用程序类型是什么))。在这种情况下,仍然没有需要立即调用.Wait()

异步运行第一个部分可能有意义,取决于它在名称中有Async,表明它不会阻塞,在这种情况下不需要,但是由于它只有1个进程而你绝对不需要异步运行DoSyncWork正在等待它完成。

我使用类似于此的模式来尽可能地保持IO和CPU的运行

public async void DoWork()
{
    Task cpuBoundTask = null;
    Task ioBoundTask = null;

    while(true)
    {
         ioBoundTask = DoIOBoundStuff();
         var ioResult = await ioBoundTask;

         if(cpuBoundTask != null)
         {
             await cpuBoundTask;
         }
         cpuBoundTask = DoCpuBoundStuff(ioResult);
    }
 }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM