Threadpool队列在第10个项目上停止

时间:2011-10-26 10:30:11

标签: c# multithreading backgroundworker threadpool

我的测试应用程序出了问题。我正在运行一个win表单应用程序,可以将请求发布到Web服务。有一个定时器,它定期将项添加到请求队列中。我有一个名为AutoManager的类,用于从队列中挑选项目并将它们发送到Web服务。

在TryKickQueue()中,它将一个IAutoProcessor添加到线程池队列中。一旦IAutoProcessor完成,它就会回调给AutoManager以从队列中删除它自己。

这工作正常并运行前10个请求没有问题但是由于某种原因我无法弄清楚第10个线程永远不会完成,所以它被卡住了。这很奇怪,因为它总是排在第10位。我做错了什么,我应该清理一下吗?

这应该发生还是可能是我无法找到的僵局?

非常感谢 尼尔

    public AutoManager(Settings _settings, Log _log)
    {
        m_sessionKicker = new BackgroundWorker();
        m_sessionKicker.DoWork += SessionKickerDoWork;
        m_sessionKicker.RunWorkerCompleted += SessionKickerRunCompleted;
        m_sessionKicker.WorkerSupportsCancellation = true;
        m_sessionKicker.RunWorkerAsync();

        m_processorQueue = new List<IAutoProcessor>();
        m_inProcessingQueue = new List<IAutoProcessor>();
    }

    private void SessionKickerDoWork(object sender, DoWorkEventArgs e)
    {
        bool bFinished = false;

        while (!bFinished)
        {
            TryKickQueue();
        }
    }

    private void TryKickQueue()
    {
        object thisObject = new Object();

        lock (thisObject)
        {
            if (m_processorQueue.Count > 0 && m_inProcessingQueue.Count < m_settings.MaxThreads)
            {
                IAutoProcessor proc = m_processorQueue[0];
                m_inProcessingQueue.Add(proc);
                m_processorQueue.RemoveAt(0);

                if (proc != null)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(proc.SendData));
                }
            }
        }
    }

    public void OnRemoveAutoProcessor(IAutoProcessor _autoProcessor)
    {
        object thisObject = new Object();

        lock (thisObject)
        {
            m_inProcessingQueue.Remove(_autoProcessor);
        }
    }

2 个答案:

答案 0 :(得分:2)

您使用m_processorQueue的锁无效。你将局部变量thisObject锁定,但这意味着每个线程都有自己的锁对象,它们永远不会等待......

声明thisObject,使其与m_processorQueue具有相同的范围和生命周期。

但是我也注意到你的bgw做了一个繁忙的循环,它将消耗大量的CPU时间。您需要一些机制来等待空队列。

如果您使用的是Fx4,请使用ConcurrentQueue。否则寻找一个良好的队列实现。

答案 1 :(得分:0)

将锁定(thisObject)从local移动到方法,从global移动到type。

    static object thisObject = new Object();
    private void TryKickQueue() 
    { 
        lock (thisObject) 
        { 
           // your logic
        } 
    } 

    public void OnRemoveAutoProcessor(IAutoProcessor _autoProcessor) 
    { 
        lock (thisObject) 
        { 
           //your logic
        } 
    }

不确定为什么要检查此m_inProcessingQueue.Count < m_settings.MaxThreads