我有一个实现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;
}
那是
TaskCompletionSource
(非费用)作为字典的值TryAdd
,如果成功,则执行昂贵的操作TaskCompletionSource.Task
然而,我仍然创建了我不使用的TaskCompletionSources
,这对我来说感觉有点难看。有关如何解决此问题的任何建议,如果没有lock
的性能影响并且没有浪费时钟周期来创建未使用的对象?