使用Concurrent Bag< T>不允许重复

时间:2017-06-14 17:31:14

标签: c# multithreading concurrency

我考虑使用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中使用相同的回调通道对象进行多次调用 - 我知道这本身就很糟糕,但无论如何我想处理它。

1 个答案:

答案 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);
            }
        }
    }

这可能很昂贵,因为在早期线程完成任务之前,每个线程都会等待锁定。