我考虑使用Concurrent Bag< T>但我不想在我的收藏中允许重复。我的想法是,做这样的事情不会是线程安全的,因为"步骤"检查和添加到集合之间:
private ConcurrentBag<IClientCallback> _callbackChannels = new ConcurrentBag<IClientCallback>();
...
public void AddCallback(IClientCallback callback) {
if (!_callbackChannels.Contains(callback))
{
_callbackChannels.Add(callback);
}
}
所以我在想这样的事情,但也许这是一个可怕的想法?
_callbackChannels = new ConcurrentBag<IClientCallback>(_callbackChannels.Union(new List<IClientCallback>() { callback }));
所以,我的问题是:这是否比检查添加方法更安全?我有什么遗失的东西,还有更好的方法吗?
我们的想法是,理论上可以在AddCallback中使用相同的回调通道对象进行多次调用 - 我知道这本身就很糟糕,但无论如何我想处理它。
答案 0 :(得分:-1)
你可以在加入包之前锁定。
private ConcurrentBag<IClientCallback> _callbackChannels = new ConcurrentBag<IClientCallback>();
private object _lockObject = new Object();
public void AddCallback(IClientCallback callback)
{
lock(_lockObject)
{
if (!_callbackChannels.Contains(callback))
{
_callbackChannels.Add(callback);
}
}
}
这可能很昂贵,因为在早期线程完成任务之前,每个线程都会等待锁定。