ConcurrentDictionary具有“昂贵”的价值

时间:2016-03-15 08:58:33

标签: .net multithreading performance concurrency concurrentdictionary

我有一个实现async方法的多线程应用程序。应用程序通过RabbitMq进行通信,有时需要进行昂贵的操作(BasicConsume上的IModel)。我有一个ConcurrentDictionary,我保留IModel(密钥),它是IBasicConsumer(值),以避免额外的往返消息代理。

在启动时,多次执行会到达代码的相同部分,如果消费者(值)存在,则会查看该部分。在前40个案例中答案是否定的,但我不想做40 BasicConsume,只有一个或两个,具体取决于提供的IModel(密钥)。

使用lock语句会导致性能损失,这是不可接受的。

目前,我正在解决以下问题

var consumerTcs = new TaskCompletionSouce<IBasicConsumer>();
if (_consumerDictionary.TryAdd(channel, consumerTcs))
{
    var newConsumer = new EventingBasicConsumer(channel);
    newConsumer.Model.BasicConsume(queue, false, newConsumer)
    consumerTcs.TrySetResult(newConsumer);
    return consumerTcs.Task;
}
else
{
    return _consumerDictionary[channel].Task;
}

那是

  1. 使用TaskCompletionSource(非费用)作为字典的值
  2. 使用TryAdd,如果成功,则执行昂贵的操作
  3. 如果不成功,则假设密钥存在并返回TaskCompletionSource.Task
  4. 然而,我仍然创建了我不使用的TaskCompletionSources,这对我来说感觉有点难看。有关如何解决此问题的任何建议,如果没有lock的性能影响并且没有浪费时钟周期来创建未使用的对象?

0 个答案:

没有答案