今天我得到了here nice answer這將解決我的問題。不幸的是,我忘了問如何鎖定。鎖定,問題問題
問題很簡單 - 在服務器中,每個連接的客戶端都會得到一個從1到500的唯一ID(可重用),這是最大的客戶端。
答案是創建一個qeue,併爲新連接使用等待元素,並在發佈時將其返回。
我不確定我是否理解正確 - 我也應該用500個元素(整數)初始化queue,並且一個接一個地返回,一旦發佈就返回?
如果是這樣,這裏鎖定什麼,我的問題主要是針對性能,因爲我使用鎖。
今天我得到了here nice answer這將解決我的問題。不幸的是,我忘了問如何鎖定。鎖定,問題問題
問題很簡單 - 在服務器中,每個連接的客戶端都會得到一個從1到500的唯一ID(可重用),這是最大的客戶端。
答案是創建一個qeue,併爲新連接使用等待元素,並在發佈時將其返回。
我不確定我是否理解正確 - 我也應該用500個元素(整數)初始化queue,並且一個接一個地返回,一旦發佈就返回?
如果是這樣,這裏鎖定什麼,我的問題主要是針對性能,因爲我使用鎖。
如果你可以使用並行擴展走了ConcurrentQueue
如果你不能,你可以找到如何通過香草薩特
實現自己在this article順便說一句,在喬恩斯基特答案是告訴你只是嘗試去隊列,如果是空的生成和使用。當你完成一個id時,只需將它排入隊列即可。沒有提及500個ID。如果您需要限制到500個ID,那麼您將需要用500個ID來初始化隊列,然後在隊列爲空時,而不是生成新隊列。爲此,consumer/producer pattern將更適合。
我不明白你想做什麼。
您可以爲已用數字填充散列表。
而且您可以將其存儲在應用程序範圍內的變量中,並在訪問該資源時使用Application.Lock和Application.Unlock方法。
像這樣的東西?
/// <summary>
/// Thread safe queue of client ids
/// </summary>
internal class SlotQueue
{
private readonly AutoResetEvent _event = new AutoResetEvent(false);
private readonly Queue<int> _items = new Queue<int>();
private int _waitCount;
/// <summary>
/// Initializes a new instance of the <see cref="SlotQueue"/> class.
/// </summary>
/// <param name="itemCount">The item count.</param>
public SlotQueue(int itemCount)
{
// Create queue items
for (int i = 0; i < itemCount; ++i)
_items.Enqueue(i);
}
/// <summary>
/// Gets number of clients waiting in the queue.
/// </summary>
public int QueueSize
{
get { return _waitCount; }
}
/// <summary>
///
/// </summary>
/// <param name="waitTime">Number of milliseconds to wait for an id</param>
/// <returns></returns>
public int Deqeue(int waitTime)
{
// Thread safe check if we got any free items
lock (_items)
{
if (_items.Count > 0)
return _items.Dequeue();
}
// Number of waiting clients.
Interlocked.Increment(ref _waitCount);
// wait for an item to get enqueued
// false = timeout
bool res = _event.WaitOne(waitTime);
if (!res)
{
Interlocked.Decrement(ref _waitCount);
return -1;
}
// try to fetch queued item
lock (_items)
{
if (_items.Count > 0)
{
Interlocked.Decrement(ref _waitCount);
return _items.Dequeue();
}
}
// another thread got the last item between waitOne and the lock.
Interlocked.Decrement(ref _waitCount);
return -1;
}
/// <summary>
/// Enqueue a client ID
/// </summary>
/// <param name="id">Id to enqueue</param>
public void Enqueue(int id)
{
lock (_items)
{
_items.Enqueue(id);
if (_waitCount > 0)
_event.Set();
}
}
}
這麼簡單的鎖就夠了。 – Thomas 2009-12-21 16:29:31
+1 w/Minor modification ... BLOCKING只是一個解決應用程序問題的方法,當沒有更多的連接可用時該怎麼做。根據系統和上下文,你可能想要返回一個錯誤代碼或拋出一個異常(或任何其他適當的錯誤處理範例)。優秀的答案否則。 – James 2009-12-21 16:31:38