![](/img/trans.png)
[英].Net 4.0 Parallel Programming - how to write data to concurrent collections?
[英]Proper use of .NET Concurrent Collections
在我嘗試創建並發Socket
操作時,我創建了以下代碼:
ConcurrentQueue<byte[]> messageQueue;
ManualResetEvent resetEvent;
Thread outThread; // -> new Thread(BeginSending);
public void BeginSending() // invoked by outThread
{
while (true)
{
resetEvent.WaitOne();
while (messageQueue.Count > 0)
{
byte[] msg;
messageQueue.TryDequeue(out msg);
// send msg via socket
}
resetEvent.Reset();
}
}
public void QueueMessage(byte[] msg) // invoked by the main thread
{
messageQueue.Enqueue(msg);
resetEvent.Set();
}
將項目添加到ConcurrentQueue
而另一個線程迭代/出列是危險的事情?
根據我的理解,許多同步集合只是單獨同步的方法,但對於concurrentQueue
和類似的集合是一樣的嗎?
( ConcurrentBag
, ConcurrentDictionary
, ConcurrentStack
)
ConcurrentQueue
本身沒問題,只要你沒有改變存儲為其元素的數組。
但是,使用ManualResetEvent
的使用模式表明有更好的解決方案:如果使用BlockingCollection<T>
,則可以避免進行手動同步。
將項目添加到ConcurrentQueue,而另一個線程迭代/出列是危險的事情?
不,這很安全。
ConcurrentQueue很好,ManualResetEvent不是:
public void BeginSending() // invoked by outThread
{
while (true)
{
resetEvent.WaitOne();
while (messageQueue.Count > 0)
{
byte[] msg;
messageQueue.TryDequeue(out msg);
// send msg via socket
}
// context change
messageQueue.Enqueue(msg);
resetEvent.Set();
// context change
resetEvent.Reset();
}
}
這樣的事件序列將導致忽略排隊的消息。 要么使用其他海報建議的BlockingCollection,要么使用信號量進行信號/等待。
並發集合設計為線程安全的。 使用它們可以自己實現它們,從而為您節省很多麻煩。
請注意,集合本身是同步的,而不是其中的數據。 更新集合中的對象而不關注其他線程可能會帶來競爭條件。
與任何類的使用一樣,如果您了解集合的用法和用例,它會有所幫助
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.