6

我有一些代码在我自己的计算机 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 项目中的任何设置?

4

3 回答 3

9

有时这种行为表明过载ThreadPool

鉴于这些是长时间运行/阻塞的任务,它们不应该被安排在 中运行ThreadPool,这是Task.Factory.StartNew使用默认值发送它们的地方TaskScheduler

IMO,Task.Factory.StartNew可能不是最适合这个,你最好启动自己的线程来运行这些循环。

ThreadStart action=()=>{
    //do your thing
};
Thread thread=new Thread(action){IsBackground=true};
thread.Start();
于 2012-08-17T17:33:54.977 回答
2

日志中是否打印了任何日志消息?你看到"MonitorMainQueue called"打印了吗?你怎么知道第二个任务已经启动但不是第一个?创建/写入日志文件可能是权限问题吗?

编辑:此外,为了回应@spender 所说的关于长时间运行的任务,使用该选项启动任务时会出现过载。

Task.Factory.StartNew(MonitorMainQueue, TaskCreationOptions.LongRunning);

于 2012-08-17T17:22:10.860 回答
1

部署到我的生产环境时我遇到了同样的问题。

问题是由于应用程序池使用的身份造成的。

默认情况下,它使用具有受限权限的 applicationPoolIdentity。

我们更改为“网络服务”并且它起作用了。

注意:我并不是说使用 NetWorkService 是最好的解决方案,但这显然是一个安全权利问题。

于 2014-07-29T12:50:44.260 回答