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 のブロックです。これで、両方のタスクが作成されますが、2 番目にのみ入力され、ログに「新しいスレッド監視キュー」が出力されることはありません。なぜなのか理解できません。リモート デバッグを試しましたが、コードに入らないため、価値のあるものは何も見つかりませんでした。

デプロイされたサーバー上のコードの動作を変更するものは見つかりませんでした。ここにいる誰もが手がかりを持っているかもしれませんか?Visual Studio プロジェクトの設定はありますか?

4

3 に答える 3

9

この種の動作は、オーバーロードされた を示している場合がありThreadPoolます。

これらは長時間実行/ブロックするタスクであるためThreadPool、 で実行するようにスケジュールTask.Factory.StartNewするべきではありませんTaskScheduler

IMOTask.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"印刷されますか?最初のタスクではなく、2 番目のタスクが開始されたことをどのように確認できますか? ログファイルの作成/書き込みの権限の問題でしょうか?

編集: さらに、@spender が実行時間の長いタスクについて言ったことに応えて、そのオプションでタスクを開始するためのオーバーロードがあります。

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

于 2012-08-17T17:22:10.860 に答える