C# 锁定和队列问题(性能)
今天我得到了一个可以解决我问题的答案。不幸的是,我忘了问锁怎么办 问题很简单-在服务器中,每个连接的客户机将获得一个从1到500的唯一ID(可重用),这是最多个客户机 答案是创建一个QUE,为新连接使用等待元素,并在释放它们时返回它们 我不确定我是否理解正确-我也应该用500个元素(int)初始化QUE,然后一个接一个地获取它们并在发布后返回C# 锁定和队列问题(性能),c#,multithreading,locking,C#,Multithreading,Locking,今天我得到了一个可以解决我问题的答案。不幸的是,我忘了问锁怎么办 问题很简单-在服务器中,每个连接的客户机将获得一个从1到500的唯一ID(可重用),这是最多个客户机 答案是创建一个QUE,为新连接使用等待元素,并在释放它们时返回它们 我不确定我是否理解正确-我也应该用500个元素(int)初始化QUE,然后一个接一个地获取它们并在发布后返回 如果是这样的话,在这里锁定怎么样?我的问题主要是针对性能,因为我使用的是锁。我不明白您想做什么 您可以填充已用数字的哈希表 您可以将其存储在应用程序范围的
如果是这样的话,在这里锁定怎么样?我的问题主要是针对性能,因为我使用的是锁。我不明白您想做什么 您可以填充已用数字的哈希表
您可以将其存储在应用程序范围的变量中,并在访问该资源时使用application.Lock和application.Unlock方法。如果您可以使用并行扩展,请选择 如果你不能,你可以通过Herb Sutter找到如何在中实现你自己的 顺便说一下,Jon Skeet的答案是告诉您只需尝试取消队列,如果为空,则生成并使用。当您处理完一个id后,只需将其排队返回即可。没有提到500个ID。如果需要限制为500个ID,则需要使用500个ID初始化队列,然后在队列为空时阻塞,而不是生成新ID。对于这一点,a更合适。像这样的东西
/// <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();
}
}
}
//
///客户端ID的线程安全队列
///
内部类SlotQueue
{
私有只读自动恢复事件_event=新自动恢复事件(false);
私有只读队列_items=new Queue();
私人int_waitCount;
///
///初始化类的新实例。
///
///物品计数。
公共SlotQueue(int itemCount)
{
//创建队列项目
对于(int i=0;i0)
return_items.Dequeue();
}
//等待的客户端数。
联锁增量(参考等待计数);
//等待项目进入队列
//false=超时
bool res=_event.WaitOne(waitTime);
如果(!res)
{
联锁减量(参考waitCount);
返回-1;
}
//尝试获取排队的项目
锁定(_项)
{
如果(_items.Count>0)
{
联锁减量(参考waitCount);
return_items.Dequeue();
}
}
//另一个线程得到了waitOne和锁之间的最后一项。
联锁减量(参考waitCount);
返回-1;
}
///
///将客户端ID排队
///
///要排队的Id
公共无效排队(int id)
{
锁定(_项)
{
_项目。排队(id);
如果(_waitCount>0)
_event.Set();
}
}
}
+1 w/轻微修改…阻塞只是解决应用程序问题的一种解决方案,即当没有更多可用连接时该怎么办。根据系统和上下文,您可能希望返回错误代码或引发异常(或任何其他相关的错误处理范例)。很好的回答,否则。