我有一些代码在我安装它/在我自己的计算机上运行时,按预期工作,Windows 7,但是当我在其他服务器(2003和2008)上运行它时却没有。代码来自我在Windows服务中使用的.NET4 WCF服务库。这是简单的。
public void monitorQueueAndDoStuff() {
MonitorRetryQueue();
MonitorMainQueue();
}
private void MonitorMainQueue() {
Log.Info("MonitorMainQueue called");
Task.Factory.StartNew(() =>
{
Log.Info("new thread monitoring queue");
// ...NMS stuff
while (!stopped) {
ITextMessage mess = null;
mess = blockingMessageCollection.Take();
sendToQueue(mess);
}
}
}
});
}
private void MonitorRetryQueue() {
Task.Factory.StartNew(() =>
{
//...NMS stuff
consumer.Listener += new MessageListener(OnRetryErrorMessage);
Log.Info("new thread monitoring second queue");
//need to be constantly up for the consumer to hang around
while (!stopped) {
Thread.Sleep(1000);
}
}
}
});
}
线程应该进入循环来完成一些工作。 BlockingCollection上的主要块。 现在,它创建了两个任务,但只进入第二个任务,它从不在日志中打印“新线程监视队列”。我不明白为什么不。我尝试了远程调试,但因为它从未输入代码,所以我看不到任何有价值的内容。
我没有找到任何会改变已部署服务器上代码行为的内容。这里的任何人都可能有线索吗? Visual Studio项目中的任何设置?
答案 0 :(得分:8)
有时,这种行为表示过载ThreadPool
。
由于这些是长时间运行/阻止任务,因此不应将它们安排在ThreadPool
中运行,Task.Factory.StartNew
将使用默认TaskScheduler
发送它们。{ / p>
IMO,Task.Factory.StartNew
可能不是最适合这种情况,你最好自己动手来运行这些循环。
ThreadStart action=()=>{
//do your thing
};
Thread thread=new Thread(action){IsBackground=true};
thread.Start();
答案 1 :(得分:1)
是否在日志中打印了任何日志消息?你看到"MonitorMainQueue called"
打印了吗?你怎么知道第二个任务开始但不是第一个?创建/写入日志文件可能是一个权限问题吗?
编辑:此外,为了回应@spender关于长时间运行任务的说法,使用该选项启动任务时会出现重载。
Task.Factory.StartNew(MonitorMainQueue, TaskCreationOptions.LongRunning);
答案 2 :(得分:1)
部署到我的生产环境时遇到了同样的问题。
问题是由于应用程序池使用的身份。
默认情况下,它使用的是具有受限权限的applicationPoolIdentity。
我们更改为"网络服务"它起作用了。
Nota:我并不是说使用NetWorkService是最好的解决方案,但它确实是一个安全问题。