Task.Factory.StartNew在部署时不执行任务

时间:2012-08-17 17:09:45

标签: c# visual-studio-2010 .net-4.0 task-parallel-library

我有一些代码在我安装它/在我自己的计算机上运行时,按预期工作,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项目中的任何设置?

3 个答案:

答案 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是最好的解决方案,但它确实是一个安全问题。