Signalr: async / awaitを使用するコンソールアプリケーションは、送信後に受信を停止します

作成日 2017年03月22日  ·  4コメント  ·  ソース: SignalR/SignalR

私は、コンソールアプリケーションのペアを使用してメッセージを送受信するスパイクに取り組んでおり、少し奇妙な動作をしました。 サブスクライバーアプリケーションでは、 awaitを使用してハブでメソッドを呼び出すと、新しいメッセージの受信を停止しました。 最初は、 Subscribeメソッドをすぐに呼び出したため、メッセージを受信しなかったことを意味していましたが、調べてみると、メソッドを呼び出すまでは非常に喜んで受信することがわかりました。

メソッドがで呼び出された場合.Wait()の代わりにawaitすべてがうまくています。

これがコンソールアプリケーションでのスレッドの処理方法に関係しているのか( SynchronizationContextを持つWPFアプリケーションとは対照的に)、C#SignalRクライアントの問題に起因しているのかわかりません。

予想される行動

await hubProxy.Invoke("Foo");を実行し、メッセージを受信し続けることができると期待します。

実際の動作

await hubProxy.Invoke("Foo");を使用すると、接続が切断されます。

再現する手順

`` `c#
クラスプログラム
{{
static void Main()
{{
Run()。Wait();
}

static async Task Run()
{{
Console.WriteLine( "[Subscriber] Enterキーを押して入力してください...");
Console.ReadLine();

var hubConnection = new HubConnection("http://localhost:39103/");
var hubProxy = hubConnection.CreateHubProxy("MyHub");
hubProxy.On<string>("OnMessage", msg =>
{
  Console.WriteLine($"Received: {msg}");
});

await hubConnection.Start();

// Receiving messages quite happily at this point

Console.WriteLine("And press Enter again to break the application...");
Console.ReadLine();

await hubProxy.Invoke("Foo", "Bar");

// NO MESSAGES FOR YOU!

Console.WriteLine("And press Enter to Exit, because computers...");
Console.ReadLine();

}
}
`` `

Bug

最も参考になるコメント

e55b89a45618d222e2c37a3b14969923c998899bで修正済み

全てのコメント4件

ただの急上昇であるにもかかわらず、これについて懸念している理由は、私が取り組んでいる実際のサービスがASP.NET WebAPIサービスとWPFデスクトップアプリケーションから消費されるためです。

これは非常に暗黙的なデッドロックです。 トレースをオンにすると、メッセージがまだクライアントによって受信されていることがわかります。前のコールバックがまだ終了していないため、コールバックは呼び出されていません。

And press Enter to Exit, because computers...
16:44:27.6966075 - b8022975-3d42-4935-952d-7c43a392d049 - WS: OnMessage({"C":"d-59F20992-B,18|S,0|T,1","M":[{"H":"ChatHub","M":"broadcastMessage","A":["adfasf","sadf"]}]})
16:44:28.6936798 - b8022975-3d42-4935-952d-7c43a392d049 - WS: OnMessage({})
16:44:31.4080330 - b8022975-3d42-4935-952d-7c43a392d049 - WS: OnMessage({"C":"d-59F20992-B,19|S,0|T,1","M":[{"H":"ChatHub","M":"broadcastMessage","A":["adfasf","adfsa"]}]})
16:44:36.2056851 - b8022975-3d42-4935-952d-7c43a392d049 - OnError(Microsoft.AspNet.SignalR.Client.Infrastructure.SlowCallbackException: Possible deadlock detected. A callback registered with "HubProxy.On" or "Connection.Received" has been executing for at least 10 seconds.)
16:44:38.6935113 - b8022975-3d42-4935-952d-7c43a392d049 - WS: OnMessage({})

あなたの側では、 Console.ReadLine();await Console.In.ReadLineAsync()変更することでこれを修正できますが、ここでの根本的な原因は、デフォルトでユーザーコードがTaskCompletionSource.SetResult(で完了したタスクと同じスレッドで実行されることです。 )。 クライアントは、設定結果を別のスレッドにディスパッチするか、TCSの作成時にTaskCreationOption.RunContinuationsAsynchronously使用する必要があります。

このスレッドは、一言で言えば私の非同期待機体験です。

e55b89a45618d222e2c37a3b14969923c998899bで修正済み

このページは役に立ちましたか?
0 / 5 - 0 評価