7

ASP.NET 3.5 webapp は、完了までに数時間かかるいくつかのタスクを開始する必要があります。明らかな理由から、これらのタスクを開始するページは、タスクが終了するのを待つことができず、応答を得るためにそれほど長く待ちたいとは思わないため、タスクは非同期でなければなりません。

これらの長時間実行されるタスクをすべて処理するヘルパー クラスがあります。これらのタスクをスケジュールして実行する主な方法は、現在次のとおりです。

public static bool ScheduleTask(TaskDescriptor task, Action action)
{
    bool notAlreadyRunning = TasksAsync.TryAdd(task);
    if (notAlreadyRunning)
    {
        Thread worker = null;
        worker = new Thread(() => 
        {
            try { action(); }
            catch(Exception e)
            {
                Log.LogException(e, "Worker");
            }
            TasksAsync.RemoveTask(task);
            workers.Remove(worker);
        });
        workers.Add(worker);
        worker.Start();
    }
    return notAlreadyRunning;
}

以前の実装では、このThreadPool.QueueUserWorkItemアプローチを使用しましたが、結果は常に同じでした。20 ~ 30 分、スレッドが中止されていたという例外がスローされます。

なぜこれが起こっているのか誰にも分かりますか?またはどのように防ぐことができますか?

より詳しい情報:

  • IIS 標準構成。
  • タスクは、データベースへのクエリや IO 操作など、何でもかまいません。

更新: 決定

ご回答ありがとうございます。どの質問を回答としてマークするかわかりません。それらはすべて有効であり、この問題の可能な解決策です。今日まで待って、投票数が最も多い回答を回答としてマークします。引き分けの場合は、最初に表示された回答を選択します。通常、それらは最も関連性の高い順に並べられます。

私が選択した解決策を知りたい人のために、これも時間の制約により、IIS のリサイクル構成を変更することでした。 「ワーカー サービス」を作成し、ASP.NET アプリと新しい「ワーカー サービス」間の通信ソリューションを使用して、長時間実行される作業を調整します。

4

2 に答える 2

4

タイムアウトを増やしたり、別のアプリプールやその他のさまざまなハックを使用したりすることで、これを機能させることができる可能性がありますが、最善の策は、実行時間の長いタスクを ui と asp.net から完全に分離し、使用することです。サービス (お勧めしません) または実行する作業をポーリングするスケジュールされたタスクのいずれか。個人的には、aws sqs/sns のようなものを使用して、実行する作業を追跡し、Windows サーバーでスケジュールされたタスクを使用して、適切な頻度でタスクをチェックします。ui/asp.net が実行する必要があるのは、実際に実行するのではなく、何かを実行する必要があるという事実をログに記録することだけです。

このメッセージ ベースのアプローチのもう 1 つの利点は、実行時間の長いプロセスが非常に長時間実行されたり、過負荷になったりした場合に、ワーカー タスクまたはサーバーを追加してそれらの要求を完了する機会があることです。

おそらく、差し迫った問題に対して実装できることは多くありませんが、より良い長期的な解決策を検討する必要があります。

于 2013-04-27T17:51:32.767 に答える