要回答你的問題,只要你鎖定了訪問權限,就可以讓多個線程訪問一個常規隊列。
對於我來說,雖然,我沒有使用,想使用隊列,鎖,讓他們線程安全的。我一直在c#中爲我的一個程序做這個。我只是使用一個普通的隊列,然後放置一個更衣室(enqueue,dequeue,count)。如果您只是鎖定訪問權限,則它是完全線程安全的。
我的設置來自教程/例子在這裏:http://www.albahari.com/threading/part2.aspx#_ProducerConsumerQWaitHandle
我的情況比你有點不同,但很相似。對我而言,我的數據可能會非常快速地出現,如果我不排隊,那麼如果多個數據同時進入,我將丟失數據。然後我有一個線程正在運行,緩慢地將項目從隊列中取出並處理它們。該切換使用AutoResetEvent來保存我的工作線程,直到數據準備好處理。在你的情況下,你會使用計時器或定期發生的事情。
我複製/粘貼我的代碼,並試圖更改名稱。希望我沒有完全打破它,因爲錯過了一些名稱變更,但你應該能夠獲得要點。
public class MyClass : IDisposable
{
private Thread sensorProcessingThread = null;
private Queue<SensorData> sensorQueue = new Queue<SensorData>();
private readonly object _sensorQueueLocker = new object();
private EventWaitHandle _whSensorEvent = new AutoResetEvent(false);
public MyClass() {
sensorProcessingThread = new Thread(sensorProcessingThread_DoWork);
sensorProcessingThread.Start();
}
public void Dispose()
{
// Signal the end by sending 'null'
EnqueueSensorEvent(null);
sensorProcessingThread.Join();
_whSensorEvent.Close();
}
// The fast sensor data comes in, locks queue, and then
// enqueues the data, and releases the EventWaitHandle
private void EnqueueSensorEvent(SensorData wd)
{
lock (_sensorQueueLocker)
{
sensorQueue.Enqueue(wd);
_whSensorEvent.Set();
}
}
// When asynchronous events come in, I just throw them into queue
private void OnSensorEvent(object sender, MySensorArgs e)
{
EnqueueSensorEvent(new SensorData(sender, e));
}
// I have several types of events that can come in,
// they just get packaged up into the same "SensorData"
// struct, and I worry about the contents later
private void FileSystem_Changed(object sender, System.IO.FileSystemEventArgs e)
{
EnqueueSensorEvent(new SensorData(sender, e));
}
// This is the slower process that waits for new SensorData,
// and processes it. Note, if it sees 'null' as data,
// then it knows it should quit the while(true) loop.
private void sensorProcessingThread_DoWork(object obj)
{
while (true)
{
SensorData wd = null;
lock (_sensorQueueLocker)
{
if (sensorQueue.Count > 0)
{
wd = sensorQueue.Dequeue();
if (wd == null)
{
// Quit the loop, thread finishes
return;
}
}
}
if (wd != null)
{
try
{
// Call specific handlers for the type of SensorData that was received
if (wd.isSensorDataType1)
{
SensorDataType1_handler(wd.sender, wd.SensorDataType1Content);
}
else
{
FileSystemChanged_handler(wd.sender, wd.FileSystemChangedContent);
}
}
catch (Exception exc)
{
// My sensor processing also has a chance of failing to process completely, so I have a retry
// methodology that gives up after 5 attempts
if (wd.NumFailedUpdateAttempts < 5)
{
wd.NumFailedUpdateAttempts++;
lock (_sensorQueueLocker)
{
sensorQueue.Enqueue(wd);
}
}
else
{
log.Fatal("Can no longer try processing data", exc);
}
}
}
else
_whWatchEvent.WaitOne(); // No more tasks, wait for a signal
}
}
你可能會看到的東西是來自Microsoft的.net的Reactive(Rx)。退房:https://msdn.microsoft.com/en-us/data/gg577611.aspx,頁面底部是一個pdf教程「固化異步藍調」:http://go.microsoft.com/fwlink/?LinkId=208528這是非常不同的東西,但也許你會看到你喜歡的東西。
你可能會想在[線程安全的集合(https://msdn.microsoft.com/en-us/library/dd997305(V = vs.110)的.aspx),特別是ConcurrentQueue讀了。 –
Micke
幾年前,我使用[ZeroMQ](http://zeromq.org/)構建了一個類似的解決方案,它負責處理產品問題和併發問題。它的工作,並仍然正常工作! – Micke
當我添加我的解決方案後,我讀了Micke的評論,我認爲你應該首先看看那些:) – mdiehl13