【问题标题】:Concurrent collection for .NET with timeouts?.NET 的并发收集超时?
【发布时间】:2013-04-10 14:49:42
【问题描述】:

我有一个并发集合。

var q = new ConcurrentQueue<int>(); // Or a stack/bag/etc...

我可以得到这样的物品。

int i;
if (q.TryDequeue(out i))
    DoStuff(i);

但我需要它,例如“等待 10 秒后再返回 false,以防有人添加新项目”:

int i;
if (q.TryDequeue(TimeSpan.FromSeconds(10), out i))
    DoStuff(i);

我可以这样写一个扩展方法:

public static bool TryDequeue<T>(
    this ConcurrentQueue<T> queue,
    TimeSpan timeout,
    out T result)
{
    // Validations...

    for (int i = 0; i < 2; i++)
    {
        if (queue.TryDequeue(out result))
            return true;
        else if (i == 1)
            return false;

        Thread.Sleep(timeout);
    }
}

但是如果有人在 5 秒内将一个项目添加到队列中,我不想再等 5 秒。

.NET 中是否有任何线程安全集合支持此功能?

【问题讨论】:

  • 理论上这听起来很适合Rx。如果有记忆,可以进行基于时间的轮询。但不确定多线程支持是什么样的。
  • @Adam:会调查一下,谢谢。

标签: c# .net collections concurrency timeout


【解决方案1】:

与其直接使用ConcurrentQueue,不如将​​其包装在BlockingCollection 中。然后你可以使用TryTake(out T, TimeSpan)

BlockingCollection 专为生产者/消费者场景设计。 (请注意,您应该同时查看TPL Dataflow。)

【讨论】:

  • 乔恩,这个答案是否仍然有效,我开始使用 BlockingCollection,现在由于线程阻塞而开始面临问题。您对 .Net Framework 的任何其他建议,例如“Channels”(似乎是特定于 .Net 核心的)
  • @Gopichandar:是的,答案仍然有效 - 但可能有很多事情会导致阻塞问题。我建议您提出一个包含minimal reproducible example 的新问题。
  • 谢谢@jon,我已经添加了一个样本。 stackoverflow.com/questions/67123617/…
猜你喜欢
  • 2011-03-09
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多