我有一個消費者和一個生產者任務的WinForms應用程序。我的生產者任務定期連接到Web服務並檢索指定數量的字符串,然後需要將其放入某種併發固定大小的FIFO隊列中。然後,我的消費者任務處理這些字符串,然後以SMS消息發送(每個消息一個字符串)。我的生產者任務調用的SOAP函數需要一個參數來指定我想要獲取的字符串數量。該號碼將取決於我的隊列中可用的空間。所以如果我有一個最大隊列大小爲100個字符串,並且隊列中有60個字符串,那麼下一次我的生產者輪詢Web服務時,我需要它來請求40個字符串,因爲那時我可以放入隊列中。使用列表的消費者/生產者模式
下面是我使用的是代表我固定大小的FIFO隊列代碼:
public class FixedSizeQueue<T>
{
private readonly List<T> queue = new List<T>();
private readonly object syncObj = new object();
public int Size { get; private set; }
public FixedSizeQueue(int size)
{
Size = size;
}
public void Enqueue(T obj)
{
lock (syncObj)
{
queue.Insert(0, obj);
if (queue.Count > Size)
{
queue.RemoveRange(Size, queue.Count - Size);
}
}
}
public T[] Dequeue()
{
lock (syncObj)
{
var result = queue.ToArray();
queue.Clear();
return result;
}
}
public T Peek()
{
lock (syncObj)
{
var result = queue[0];
return result;
}
}
public int GetCount()
{
lock (syncObj)
{
return queue.Count;
}
}
我的製片任務目前不指定我從Web服務需要串的數量,但它似乎就像它可以像獲取隊列中的當前項目數(q.GetCount())一樣簡單,然後從我的最大隊列大小中減去它。但是,儘管GetCount()使用鎖,但GetCount()退出後不可能,我的使用者任務可能會處理隊列中的10個字符串,這意味着我實際上無法將隊列保持爲100%充分?
此外,我的消費者任務基本上需要「偷看」隊列中的第一個字符串,然後嘗試通過SMS消息發送消息。如果郵件無法發送,我需要將該字符串保留在隊列中的原始位置。我首先想到的是,「偷看」隊列中的第一個字符串,嘗試通過SMS消息發送它,然後如果發送成功,則將其從隊列中刪除。這樣,如果發送失敗,字符串仍然在隊列中的原始位置。這聽起來合理嗎?
您可能要考慮使用'System.Collection.Concurrent.ConcurrentQueue'而不是'List ',因爲那樣會爲您處理很多鎖定。 –