C# 线程池队列在第10项上暂停
我的考试申请有问题。我正在运行一个win form应用程序,它可以将请求发布到web服务。有一个计时器,它定期将项目添加到请求队列中。我有一个名为AutoManager的类,用于从队列中拾取项目并将其发送到web服务 在TryKickQueue()中,它将IAutoProcessor添加到线程池队列中。一旦IAutoProcessor完成,它将调用AutoManager将自己从队列中移除 这工作正常,运行前10个请求没有问题,但是由于某种原因,我无法确定第10个线程永远不会结束,因此它会卡住。这很奇怪,因为总是第十天。我做错什么了吗?我应该清理一下吗 这是应该发生还是可能是一个我一直找不到的僵局 非常感谢 尼尔C# 线程池队列在第10项上暂停,c#,multithreading,backgroundworker,threadpool,C#,Multithreading,Backgroundworker,Threadpool,我的考试申请有问题。我正在运行一个win form应用程序,它可以将请求发布到web服务。有一个计时器,它定期将项目添加到请求队列中。我有一个名为AutoManager的类,用于从队列中拾取项目并将其发送到web服务 在TryKickQueue()中,它将IAutoProcessor添加到线程池队列中。一旦IAutoProcessor完成,它将调用AutoManager将自己从队列中移除 这工作正常,运行前10个请求没有问题,但是由于某种原因,我无法确定第10个线程永远不会结束,因此它会卡住。这
public AutoManager(设置_设置,日志_日志)
{
m_sessionKicker=新的后台工作人员();
m_sessionKicker.DoWork+=SessionKickerDoWork;
m_sessionKicker.RunWorkerCompleted+=SessionKickerRunCompleted;
m_sessionKicker.workers支持扫描单元=真;
m_sessionKicker.RunWorkerAsync();
m_processorQueue=新列表();
m_inProcessingQueue=新列表();
}
私有void SessionKickerDoWork(对象发送方,DoWorkEventArgs e)
{
bool bFinished=false;
而(!b完成)
{
TryKickQueue();
}
}
私有void TryKickQueue()
{
对象thisObject=新对象();
锁定(此对象)
{
if(m_processorQueue.Count>0&&m_inProcessingQueue.Count
您对使用m_processorQueue的锁定无效。您正在锁定局部变量thisObject,但这意味着每个线程都有自己的锁定对象,它们永远不会等待
声明此对象
,使其与m\u processorQueue
具有相同的作用域和生存期
但我也注意到,你的bgw做了一个繁忙的循环,它将消耗大量的CPU时间。您需要某种机制来等待空队列
如果您使用的是Fx4,则使用ConcurrentQueue。否则,请寻找队列的良好实现 将锁(thisObject)从本地移动到方法,从全局移动到类型
static object thisObject = new Object();
private void TryKickQueue()
{
lock (thisObject)
{
// your logic
}
}
public void OnRemoveAutoProcessor(IAutoProcessor _autoProcessor)
{
lock (thisObject)
{
//your logic
}
}
不确定为什么要检查此
m\u inProcessingQueue.Count
无法直接锁定m\u processorQueue?谢谢,声明锁定修复了一些问题。另外,在繁忙循环中添加睡眠也解决了应用程序因循环不断锁定而暂停时的其他问题。现在这应该足够了,但一旦我升级到.net4.0,我就可以使用适当的并发库了。谢谢你的快速回复。Neil@Mario:实际上,是的。但使用单独的对象被认为是“最佳实践”,以防其他代码(队列本身)锁定它。最好是对储物柜进行完全和唯一的控制。为什么要使其静止?队列不是。在这种情况下,OnRemoveAutoProcessor(IAutoProcessor\u autoProcessor)是一个公共方法。
static object thisObject = new Object();
private void TryKickQueue()
{
lock (thisObject)
{
// your logic
}
}
public void OnRemoveAutoProcessor(IAutoProcessor _autoProcessor)
{
lock (thisObject)
{
//your logic
}
}