18

レポートをキュー形式で処理するように設計された webapi があります。アプリケーションが実行する手順は次のとおりです。

  • コンテンツを受け取る
  • コンテンツをオブジェクトにマップし、キューに配置します
  • キュー内の保留中のアイテムのポーリング
  • キュー内のアイテムを 1 つずつ処理する

Entity Framework を使用して、次のようなキュー項目のデータベースを作成することを考えていました。

public class EFBatchItem
{
    [Key]
    public string BatchId { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateCompleted { get; set; }
    public string BatchItem { get; set; }
    public BatchStatus Status { get; set; }
}

私の質問 - NServiceBus、BlockingCollection、または ConcurrentQeueue を使用して、データベースを常にポーリングし、保留中のアイテムを 1 つずつ引き出すよりも効率的な方法はありますか? 以前にキューを使用したことがありません。

1 つの考えは、タスクのキューを作成し、別のスレッドですべての保留中のタスクを処理することです。スレッドを使用してキューを処理する最も効率的な方法に多少似ていますが、最も効率的なルートを確実に使用したいと考えています。

編集:ここで私が持っている大きな質問は、進行状況をユーザーに表示する最良の方法です。ユーザーがコンテンツを送信すると、新しいページが表示され、バッチ識別子でステータスを表示できます。ユーザーに通知するには、MSMQ または NServiceBus が必要ですか? これは、REquest/Acknowledge/Push パラダイムのバリエーションのように見えますか?

4

4 に答える 4

27

私見ですが、ASP.NET Web API アプリケーションは、これらのバックグラウンド タスクを単独で実行するべきではありません。リクエストを受信し、(指定したように)キュー内に貼り付け、受信したメッセージの成功または失敗を示す応答を返すことのみを担当する必要があります。このアプローチには、 RabbitMQなどのさまざまなメッセージング システムを使用できます。

通知に関しては、いくつかのオプションがあります。クライアントが処理が完了したかどうかを確認できるエンドポイントを持つことができます。または、クライアントがサブスクライブできるストリーミング API エンドポイントを提供することもできます。この方法では、クライアントはサーバーをポーリングする必要がありません。サーバーは、接続されているクライアントに通知できます。ASP.NET Web API には、これを行う優れた方法があります。次のブログ投稿では、その方法について説明しています。

この種類のサーバーからクライアントへの通知には、SignalRを検討することもできます。

ASP.NET Web API アプリケーションのバックグラウンド タスクが難しい理由は、AppDomain を維持する責任があるからです。これは、IIS でホストしている場合は特に面倒です。次のブログ投稿は、私が言いたいことを本当によく説明しています。

于 2013-02-05T16:20:39.537 に答える
7

これは NuGet パッケージであり、HangFire と呼ばれます - https://github.com/HangfireIO/Hangfire。タスクは、apppool のリサイクル後も存続します。

于 2014-11-17T13:30:19.470 に答える