2

Web ロールにいくつかのワーカー スレッドがあります。OnStartメソッドで作成されます。

Task.Factory.StartNew(() => DoWorkAsync(), TaskCreationOptions.LongRunning);

次に、DoWorkAsyncメソッドはキューのポーリングを続行し、時間のかかる作業を行います。実際の作業には、クエリ ジョブを送信して結果が返されるまで数分かかります。それらの機能はasyncパターンにあります。トップレベルのDoWorkAsyncメソッドを実装する正しい方法は何ですか? 次のようにすると、ここでは一種のブロッキングになり、1 つだけPollingQueueAndWorkAsync()が呼び出されます。

public async void DoWorkAsync()
{
  while (_continue)
  {
    await PollingQueueAndWorkAsync();
  }
}

それとも以下?別のスレッドでメソッドを実行し続けるため、正しく見えません。

public async void DoWorkAsync()
{
  while (_continue)
  {
    Task.Run(() => PollingQueueAndWorkAsync());
  }
}

コードを「ずっと非同期」になるようにリファクタリングしようとしていました。しかし、最上位のワーカー メソッドではどのように終了する必要があるのでしょうか?

[アップデート]

さらに試した後、ここに私が持っているものがあります:

public async void DoWorkAsync()
{
  while (_continue)
  {
    Task.Run(async () => await PollingQueueAndWorkAsync());
  }
}

新しいメッセージがキューに追加され続けるため、このループはキュー内のメッセージと同じ数を処理できます。ただし、これをしばらく実行すると、メモリ例外がスローされます。あまりにも多くの継続を作成するためですか?では、SemaphoreSlim を使用してタスクの数を調整する必要がありますか?

4

2 に答える 2

2

私は通常、リクエストに関連付けられていない ASP.NET で実行されるコードを思いとどまらせます。ただし、独立したワーカーとして慎重に記述されている場合 (およびそのように聞こえます)、私のブログのBackgroundTaskManager型を使用できます。

BackgroundTaskManagerは同期タスクと非同期タスクの両方を認識し、これらのタスクは ASP.NET ランタイムに登録されて、リサイクルによってタスクが予期せず終了する可能性を最小限に抑えます。また、この型は、いつ正常に終了する必要があるかを検出するために使用できるCancellationToken呼び出しBackgroundTaskManager.Shutdownを公開します。PollingQueueAndWorkAsync

于 2013-10-12T04:16:40.147 に答える
0

次のようにポーリング スレッドを作成する必要があります。

public async void DoWorkAsync()
{
    await Task.Run(() => PollingQueueAndWorkAsync());
}

次に、スレッド自体の「_continue」をチェックして、作業がキャンセルされたときにクリーンに終了できるようにする必要があります。

于 2013-10-12T01:50:06.043 に答える