2

次の方法で受信メッセージを処理する WCF サービスがあります。

public bool ProcessMessage(string message)
{
    var returnValue = GetReturnValue();

    Task.Run(() => {
        //do some things with the message
        UpdateDatabase();
        SendRepliesOverNetwork();
    });

    return returnValue;
}

できるだけ多くのメッセージを処理するために、ここにタスクを追加しました。returnValue をできるだけ早く呼び出し元に返し、Task に任せたいと考えています。

私の質問: 待機可能な非同期データベース呼び出しを使用したり、ネットワーク経由で応答に非同期メソッドを使用したりする利点はありますか?

これによりコンテキストの切り替えが多すぎる可能性があると思うので、私は用心しています。負荷がかかった状態で 100 以上のスレッドを使用するアプリを既に確認しています。

4

2 に答える 2

8

まず、一歩下がって、早く戻ることが良い考えかどうかを本当に尋ねることをお勧めします. あなたがしていることは通常危険です。実際の処理を行う前に、クライアントに「OK」を返しています。これは、「returnValue」がアクションの完了を意味するものではなく、「SendReplies」を受信したときにのみ完了と見なすことをクライアントが知っている場合にのみ良い考えです。

そうは言っても、可能な限りすべてを非同期にすることで、何らかのメリットが得られるはずです。すべてのタスクがノンブロッキングである場合、スレッド プールをより有効に活用できます (コンテキストの切り替えが少なくなります)。

public bool ProcessMessage(string message)
{
  var returnValue = GetReturnValue();

  Task.Run(async () => {
    //do some things with the message
    await UpdateDatabaseAsync();
    await SendRepliesOverNetworkAsync();
  });

  return returnValue;
}
于 2013-04-02T17:51:53.603 に答える
4

このアプローチにはいくつかの潜在的な問題があることがわかります。

まず、IIS で WCF サービスをホストしている場合、要求よりも長く存続するバックグラウンド スレッドを使用することは絶対に避けてください。要求が完了すると、IIS は自由に全体AppDomainを取り壊すことができます。これにより、すべてのバックグラウンド作業が極度の偏見で中止されます。

次に、既存の作業が増えている場合、WCF は要求を抑制します。このパターンでは、リクエストを迅速に処理しているため、スレッド プールのキューに入れられた作業の量が際限なく増加する可能性があります。


WCF 非同期サービス メソッドを使用してみることができます。これにより、IO (データベースとネットワーク アクセス) を待機しているだけのスレッドが解放され、スループットが向上します。

このアプローチに関する詳細な記事がここにあります。Dan Rigsby: Async Operations in WCF

また、MSDN には次のセクションがあります。WCF: Synchronous and Asynchronous Operations

于 2013-04-02T17:52:35.353 に答える