The .NET core client for signalr have a HubConnection
class that can be used in the following way.
HubConnection connection = new HubConnectionBuilder()
.WithUrl("https://localhost:44321/hub")
.Build();
await connection.StartAsync();
connection.On<SomeEvent>("HubMethodName", (ev) => Console.WriteLine("EventHandler"))
I want to do some asynchronous work in the event handler, but it is not immediately obvious to me how, since most of the overloads expection an Action
. Using async void
works, but I'm not sure that's a good idea. Also, there is an overload with the signature On(string methodName, Type[] parameters, Func<object[], Task>) handler)
which is promising, but I guess I would have expected one with On<T>(string methodName, Func<T, Task> handler)
. I can make an extension method with that signature myself, but when it is not there to begin with, I'm thinking that I've might have missed something important?
The problem with async void
methods is that they can crash your app if there's an unhandled exception. Read here and here.
Those articles do say that async void
is allowed only because of events, and these are events we're talking about. But it's still true that an exception can crash your whole app. So if you are going to it, make sure you have try
/catch
blocks anywhere an exception could possibly be thrown (but still, exceptions could happen inside your catch
blocks when you try to log it).
But async void
methods can also cause unexpected behaviour because the code that calls it is not waiting for it to complete before going off and doing something else.
Remember that the benefit of await
is that ASP.NET can go off and do something else and come back to the rest of the code later. Usually that's good. But in this specific case, it can mean that two (or more) incoming messages can get processed at the same time and it's a toss up for which ones finishes first (the first that finishes getting processed may not be the first one that came in). Although that may or may not matter in your case.
You might be better off just making it synchronous, and wait for the stuff that you can't make synchronous:
connection.On<SomeEvent>("HubMethodName", HandleHubMethodName);
private void HandleHubMethodName(ev) {
SomeAwaitableThing().GetAwaiter().GetResult();
}
See here and here for the benefit of using .GetAwaiter().GetResult()
rather than .Wait()
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With