web-dev-qa-db-ja.com

クライアントを呼び出すときに、Signarサーバー側のメソッドを非同期にする必要がありますか?

私は次の「SignalRチュートリアル」に従っています: http://www.asp.net/signalr/overview/hubs-api/hubs-api-guide-server

それで、この単純なチャット方法を仮定しましょう:

public void Send(string name, string message)
{
     // Call the addNewMessageToPage method to update clients.
     Clients.All.addNewMessageToPage(name, message);
}

50000人のユーザーがいるチャットルームがあるとします。次のように、Sendメソッドを非同期に変更する利点はありますか?

 public async Task Send(string name, string message)
 {
     // Call the addNewMessageToPage method to update clients.
     await Clients.All.addNewMessageToPage(name, message);
 }
  • IIS(チャットを公開したユーザーの)現在の要求を保持し、すべてのクライアントに通知されるまで待機しますか?
  • 「クライアント」への呼び出しは内部で完全に非同期であり、要求はこの時点で解放されますか?

ありがとうございました!

25
Daniel Marcotte

タスクを待つ必要がある唯一の理由は、スケールアウトを使用しているときです。デフォルトでは、メモリ内のメッセージバスは完了したタスクを返します。これは、操作が非常に高速であるため、非同期にする意味がないためですが、必要に応じて行うことができます。あなたの質問に答えるには:

  • メソッド呼び出しを実行する同じ呼び出しスタック上のクライアントには送信しません(たとえば、Clients.All.addNewMessageは、メッセージバスへの公開以外は何も待機しません)。リクエストスレッドは、クライアントが何かを受信するのを待つことはありません(通常の呼び出しについて、クライアントがSignalRでメッセージを受け取るのを待つことはサポートされていません)。

  • コールサイトでawaitを使用しなくても、常に非同期です。実際にクライアントへの書き込みを行うメッセージブローカーがあります。そのメソッドを呼び出すときは、メッセージをバッファに入れるだけです。将来のある時点で、そのメッセージはクライアントに配信されます。

スケールアウトシナリオでは、クライアントメソッドを呼び出すと、外部サービス(sql、redis、サービスバス)にメッセージが送信されますが、失敗する可能性があるため、例外が監視されるようにタスクを待機する必要があります。

お役に立てば幸いです

43
davidfowl