今天我得到了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