【问题标题】:Thread safe collection that supports removing items支持删除项目的线程安全集合
【发布时间】:2012-03-19 09:13:04
【问题描述】:

我似乎找不到支持简单 Remove() 函数的 .NET 线程安全/并发收集,在该函数中我可以删除特定项目或传入谓词以基于该函数删除项目。我试过了:

BlockingCollection<T>
ConcurrentQueue<T>
ConcurrentStack<T>
ConcurrentBag<T>

有谁知道支持这种行为的集合,还是我必须创建自己的集合?

我希望能够从线程安全队列中获取下一个项目而不删除它,然后如果满足某个条件,则继续删除它。

【问题讨论】:

  • “抓取下一个项目......然后......继续删除它” - 同时其他线程可以做什么?
  • 只有2个线程,一个将项目添加到队列中,另一个将项目取出并触发一个事件。如果事件返​​回成功,则该项目必须从队列中移除。

标签: c# collections concurrency thread-safety concurrent-programming


【解决方案1】:

你试过ConcurrentDictionary吗?它有一个TryRemove 方法,因此如果您将键视为谓词,那么您将删除正确的项目。

【讨论】:

  • 谢谢,这非常接近我的需要。但是,有一个简单的列表仍然很好,因为我不需要键/值对。
  • @Sean 我不知道 C# 中有类似的东西(或者至少没有开箱即用的东西)。您可以忽略该值并像List 一样使用ConcurrentDictionary(没有重复值)。您可以像遍历列表一样遍历键,并且值的唯一开销是它使用了更多的内存。您可以通过使用非常小的原语(bool 或其他东西)将其最小化。
【解决方案2】:

您确定ConcurrentQueue&lt;T&gt; 不适合您的需求吗?它有一个 TryPeek 方法和一个 TryDequeue 方法,可以完全按照您在上一段中描述的方式进行操作。

【讨论】:

  • 我需要它来支持 Remove() 函数,在该函数中,我可以删除特定项目或传入谓词以基于此删除项目。例如 TryDequeue() 只是删除队列中的下一项,不一定是您想要的特定项。
  • 好的,但是在队列中你只能从头部取一个项目,所以你想要的不是队列......在这种情况下,你所说的“下一个”项目是什么意思?
【解决方案3】:

此处的其他答案不直接回答问题,或提供可能不受欢迎的限制。例如,ConcurrentDictionary 使用键来防止添加重复实例。

SynchronizedCollection 似乎是需要的,因为它是线程安全的并且包含一个 Remove 方法。

https://docs.microsoft.com/en-us/dotnet/api/system.collections.generic.synchronizedcollection-1?view=dotnet-plat-ext-5.0

代码示例:

SynchronizedCollection<string> FilePathsToIgnore = new SynchronizedCollection<string>();
...

FilePathsToIgnore.Add(someFileName);
...

if(FilePathsToIgnore.Contains(fileName))
{
    FilePathsToIgnore.Remove(fileName);
}


【讨论】:

    猜你喜欢
    • 2012-07-26
    • 2011-01-21
    • 1970-01-01
    • 2017-01-07
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    • 2020-06-08
    相关资源
    最近更新 更多