异步队列实现。Wait()比等待更快

问题描述 投票:0回答:1

为了提供可以依次排队并执行async方法的生产者-消费者功能,我正在尝试实现一个异步队列。我注意到在大型应用程序中使用它的主要性能问题。

async Task Loop() {
     while (true) {
         if (!_blockingCollection.TryTake(out var func)) continue;
         await func.Invoke();       
     }
}

生产方:

public void Add(Func<Task> func) {
    _blockingCollection.Add(func);
}

当我用await func.Invoke()代替func.Invoke().Wait()而不是正确等待它时,性能会大大提高。

为什么? 使用BlockingCollection的异步队列是个坏主意吗?

什么是更好的选择?

c# async-await producer-consumer
1个回答
0
投票

为什么?

问题中没有足够的信息来提供答案。

正如其他人所指出的那样,循环当前存在消耗CPU的旋转问题。

同时,我至少可以回答这一部分:

使用BlockingCollection的异步队列是个坏主意吗?

什么是更好的选择?

使用异步兼容队列。例如,TPL Dataflow中的ChannelsBufferBlock / ActionBlock

使用频道的示例:

async Task Loop() {
  await foreach (var func in channelReader.ReadAllAsync()) {
    await func.Invoke();
  }
}

或者如果您尚未使用.NET Core:

async Task Loop() {
  while (await channelReader.WaitToReadAsync()) {
    while (channelReader.TryRead(out var func)) {
      await func.Invoke();
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.