问题标签 [concurrent-collections]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
4788 浏览

c# - 具有固定大小 FIFO 队列的生产者/消费者模式

我需要围绕固定大小的 FIFO 队列实现生产者/消费者模式。我认为围绕 ConcurrentQueue 的包装类可能适用于此,但我不完全确定(而且我以前从未使用过 ConcurrentQueue)。这里的转折是队列只需要保存固定数量的项目(在我的例子中是字符串)。我的应用程序将有一个生产者任务/线程和一个消费者任务/线程。当我的消费者任务运行时,它需要及时将队列中存在的所有项目出列并处理它们。

对于它的价值,我的消费者处理排队的项目只不过是通过 SOAP 将它们上传到不是 100% 可靠的网络应用程序。如果无法建立连接或调用 SOAP 调用失败,我应该丢弃这些项目并返回队列以获取更多信息。由于 SOAP 的开销,我试图最大化队列中可以在一个 SOAP 调用中发送的项目数。

有时,我的生产者添加项目的速度可能比我的消费者删除和处理它们的速度要快。如果队列已经满了并且我的生产者需要添加另一个项目,我需要将新项目排入队列,然后将最旧的项目出队,以便队列的大小保持固定。基本上,我需要始终保留队列中生成的最新项目(即使这意味着某些项目没有被消耗,因为我的消费者当前正在处理以前的项目)。

关于生产者保持队列中的项目数量固定,我从这个问题中发现了一个潜在的想法:

固定大小的队列,在新入队时自动将旧值出列

我目前正在使用 Enqueue() 方法围绕 ConcurrentQueue 使用包装类(基于该答案),如下所示:

我在队列上创建了一个具有大小限制的类的实例,如下所示:

我启动了我的生产者任务,它开始填充队列。当添加项目导致队列计数超过最大大小时,我的 Enqueue() 方法中的代码似乎可以正常工作,以从队列中删除最旧的项目。现在我需要我的消费者任务来使项目出列并处理它们,但这是我的大脑感到困惑的地方。为我的消费者实现 Dequeue 方法的最佳方法是什么,该方法将在某个时刻拍摄队列的快照并将所有项目出列以进行处理(在此过程中,生产者可能仍在将项目添加到队列中)?

0 投票
1 回答
300 浏览

.net - TSQL ADO.NET 返回不正确的行数

在 C# .NET 4.0 中有一个 BlockingCollection 取自

阻塞集合

示例 BC_AddTakeCompleteAdding

我的问题是 .NET 中的 SQLCommand.ExecuteNonQuery 返回错误的行数。
更新在主键上,所以应该得到一行。
有时会得到正确的数字。
在 .NET 中经常得到大于 1 (100-10000) 的数字。
即使针对相同的 PK 运行完全相同的 TSQL,它也不总是相同的错误数字。
每次都可以将TSQL复制粘贴到SSMS并得到正确答案(1)。

声明使用的变量并且没有其他变量被命名为 rowsRet5

检查了该 textHash 值,仅更新了一行。
它似乎执行了正确的更新,但报告了错误的计数。
鉴于计数是错误的,不愿意在生产数据上使用它。

该命令位于消费者端的末尾。
在此更新之上有两个 .BeginExecuteNonQuery。
这些更新针对不同的表,不引用 docSVsys。
这些表确实有对 docSVsys 的 FK 引用。
在调试中,如果我停止回调(减慢速度),那么我不会收到此错误。
我想知道任务中的 BeginExecuteNonQuery 是否不是问题。
这个错误的 rowCount 与任何一个异步 rowCount 都不匹配,但在同一范围内。

此基本代码已处理数百万行。
没有改变任何TSQL。
转换为生产者消费者时它变坏了。

要将文档标记为正在进行中,请在生产者端使用非常相似的 TSQL,它没有问题。该循环也有一个 BeginExecuteNonQuery。

0 投票
2 回答
3668 浏览

c#-4.0 - 并行 foreach 并发字典添加

我有电话簿中的条目:姓名+地址。来源在一个网站上,计数超过 1K 条记录。

问题是:

我如何使用/ ConcurrentDictionary实现ParallelForeach

我还不如问它会更好地执行:

ConcurrentDictionary&ParallelForeach

对比

Dictionary&foreach

由于名称不允许重复作为键,而且我认为我理解正确,只有当键不存在时才ConcurrentDictionary具有自己的 add() 内置函数。TryAdd所以不允许添加已经处理好的重复键的问题,所以从那时起我可以清楚地看到平衡正在转向ConcurrentDictionary而不是标准顺序Dictionary

那么如何从任何给定的数据源添加名称和地址并通过 Parallelforeach 将其加载到 ConcurrentDictionary

0 投票
1 回答
3009 浏览

c# - 并发队列的使用>

我基本上是在寻找从线程中的相机获取的图像集合的容器。由于 ConcurrentQueue 是线程安全的,我想使用它。但是在调试我的代码时,我发现这篇文章

如果元素很小,您可能永远不会注意到这一点。但是,如果元素占用大量资源(例如,每个元素都是一个巨大的图像位图),您可能会看到这种影响(一种解决方法是将包装器对象排队,例如使用 a ConcurrentQueue<StrongBox<T>>而不是 aConcurrentQueue<T>和 null在包装器出队后,包装器对 T 值的引用)。

据我所知,StrongBox是一种原始价值的包装。这是否意味着我必须存储另一个图像集合?

所以我正在寻找ConcurrentQueue<StrongBox<T>>.我从谷歌找到的唯一的东西就是这个代码的用法或例子。

0 投票
1 回答
2155 浏览

c# - 为什么 Collections.Generic.Queue 没有 Synchronized 方法但 Collections.Queue 有?

System.Collections.Queue类具有Queue.Synchronized返回线程安全队列实现的方法。

但是通用的,System.Collections.Generic.Queue 没有Synchronized方法。在这一点上,我有两个问题:

  1. 为什么通用的没有这种方法?这是一个框架 API 设计决策吗?
  2. 返回的队列 Queue.Synchronized与类有何不同ConcurrentQueue<T>

谢谢。

0 投票
1 回答
17455 浏览

java - 何时使用 ConcurrentHashMap

可能重复:
ConcurrentHashMap 和 Collections.synchronizedMap(Map) 有什么区别?

我正在阅读 HashMap、Collenctions.synchonizedMap 和 ConcurrentHashMap 之间的差异。我的理解是 Collections.synchronizedMap 对整个集合应用了锁,因此会产生性能开销。但是 ConcurrentHashMap 不使用同步。它使用段来实现结果,因此它提供了与 HashMap 相似的性能。

请提出我的理解是否正确。此外,如果是这种情况,即使可能没有多个线程访问它,我是否可以在任何地方使用 ConcurrentHashMap ?

0 投票
2 回答
590 浏览

c# - IProducerConsumerCollection.TryAdd/.TryTake - 他们什么时候返回真/假?

当我调用IProducerConsumerCollection<T>.TryAdd(<T>)或者IProducerConsumerCollection<T>.TryTake(out <T>)这些是否会因为另一个线程正在使用该集合而失败?

或者,即使在其他线程完成收集之后,如果有空间可以添加或采取某些东西,它总是会返回 true?

我在这里看不到任何东西:http: //msdn.microsoft.com/en-us/library/dd287147.aspx

0 投票
2 回答
128 浏览

c# - 添加到并发集合

使用并发集合(例如 ConcurrentDictionary)时,我应该使用 TryAdd 方法,还是只使用普通的旧索引分配?我的意思是,TryAdd 方法在添加时会阻塞,所以如果另一个线程试图删除该值,它必须等到添加完成?

0 投票
1 回答
662 浏览

java - 与生产者/消费者线程重叠 50% 的滑动窗口

我在Java中有以下场景:

  • 1 个生产者线程将事件对象存储到队列中。阻止它不是一种选择。它应该始终只将每个元素存储在队列的末尾并退出(因此没有有界队列)。
  • 1 个消费者线程等待队列中包含 WINDOW_SIZE 个事件。然后它应该从队列中检索所有 WINDOW_SIZE 事件以进行处理,但只删除其中的一半(即 WINDOW_SIZE/2),以获得 50% 的重叠。

我的问题是,您将使用哪个(并发)集合来有效地实现这一点?这些事件在资源有限的设备(运行 Android 的手机)上以 100Hz 的频率出现。我想过使用以下内容,但似乎都不合适:

  1. ConcurrentLinkedQueue,每次修改时检查队列大小,并在 WINDOW_SIZE 事件可用时在消费者中使用 peek()/poll()。这似乎有点麻烦。
  2. 一个 ArrayBlockingQueue,再次检查队列大小,并使用 drainTo()。但是,该方法具有以下文档:“[...] 此外,如果在操作进行时修改了指定的集合,则此操作的行为是未定义的。[...]”。这对于并发集合来说似乎有点奇怪。

这是一些示例代码:

顺便说一句,我也在使用 Google Guava,所以如果那里有我没听说过的不错的收藏,请参考我。

所以:有什么好主意如何有效和干净地解决这个问题?

0 投票
1 回答
1035 浏览

c# - C# 节流 For 循环

初始情况

我正在开发一个 .NET Framework 4.0、C#、Winform 应用程序。应用程序将在 GridView 中列出(并测试)WebServiceOperations(当前有 60 个 DataRows => WebServiceOperations)。

客观的

我必须通过单击按钮来测试/调用所有这些操作。每个操作都会创建一个类的新实例。在这个类中,我调用 WebServiceOperation async 并等待结果。然后对结果进行验证。整个代码使用委托和事件可以顺利运行。

现在是挑战/问题:单击该按钮时,我使用 for 循环 (int i = 0; i < gridViewWsOperations.RowCount; i++) => 换句话说,目前我正在对他们进行 60 次操作'同时' => 服务器同时处理 60 个请求时超载,我得到超时。所以我需要以某种方式限制并发请求的数量,让我们同时说 10 个。考虑一下,for 循环(我必须将请求排入队列)与我将请求出列的方法(process_result 事件)不在同一个线程中。我使用 ConcurrentQueue 进行了尝试,因为这种类型的集合似乎是线程安全的。

链接

MSDN 上的并发队列

一个示例代码真的很有帮助!

--- 这是我的解决方案/示例代码 ---