私は C# アプリケーションに変更を加えるよう依頼された Java プログラマーです。私は C# を使って 1 週間が経ちましたが、ついにドキュメントを見ても解決策が見つからず、Google で検索しても解決策が見つからないところまで来ました。
この場合、MSMQ に到着するメッセージを処理する Windows サービスがあります。メッセージが受信されると、現在リッスンしているスレッドがそれを取得し、数秒かかる操作を実行するためにオフになります。
public void Start()
{
this.listen = true;
for (int i = 0; i < Constants.ThreadMaxCount; i++)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(this.StartListening), i);
}
...
private void StartListening(Object threadContext)
{
int threadId = (int)threadContext;
threads[threadId] = Thread.CurrentThread;
PostRequest postReq;
while(this.listen)
{
System.Threading.Monitor.Enter(locker);
try
{
postReq = GettingAMessage();
}
finally
{
System.Threading.Monitor.Exit(locker);
}
}
...
}
GettingAMessage() には、メッセージをリッスンする次の行があります。
Task<Message> ts = Task.Factory.FromAsync<Message>
(queue.BeginReceive(), queue.EndReceive);
ts.Wait();
問題は、Stop() メソッドが呼び出され、MSMQ にメッセージが送信されない場合、すべてのスレッドがそこで待機してメッセージを待機することです。タイムアウトを使用してみましたが、その方法は私にはエレガントではないようです (そして、タスク ファクトリに切り替えたので、現在それらを実装する方法がわかりません)。これに対する私の解決策は、各スレッドの参照を配列に追加して、それらをキャンセルできるようにすることでした。以下は、作成後に各ワーカー スレッドによって呼び出されます。
threads[threadId] = Thread.CurrentThread;
そして、によって中止されることになっています
public void Stop()
{
try
{
this.listen = false;
foreach(Thread a in threads) {
a.Abort();
}
}
catch
{...}
}
これがスレッドをシャットダウンしない理由について何かアドバイスはありますか? (または、さらに良いことに、ts.Wait() を適切にキャンセルする方法をどこで探すべきか誰か教えてもらえますか?)