C# 锁定和队列问题(性能)

C# 锁定和队列问题(性能),c#,multithreading,locking,C#,Multithreading,Locking,今天我得到了一个可以解决我问题的答案。不幸的是,我忘了问锁怎么办 问题很简单-在服务器中,每个连接的客户机将获得一个从1到500的唯一ID(可重用),这是最多个客户机 答案是创建一个QUE,为新连接使用等待元素,并在释放它们时返回它们 我不确定我是否理解正确-我也应该用500个元素(int)初始化QUE,然后一个接一个地获取它们并在发布后返回 如果是这样的话,在这里锁定怎么样?我的问题主要是针对性能,因为我使用的是锁。我不明白您想做什么 您可以填充已用数字的哈希表 您可以将其存储在应用程序范围的

今天我得到了一个可以解决我问题的答案。不幸的是,我忘了问锁怎么办

问题很简单-在服务器中,每个连接的客户机将获得一个从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/轻微修改…阻塞只是解决应用程序问题的一种解决方案,即当没有更多可用连接时该怎么办。根据系统和上下文,您可能希望返回错误代码或引发异常(或任何其他相关的错误处理范例)。很好的回答,否则。