Signalr .net核心客户端中的异步处理程序

Hea*_*eap 5 signalr.client

用于Signalr的.NET核心客户端具有HubConnection可按以下方式使用的类。

HubConnection connection = new HubConnectionBuilder()
            .WithUrl("https://localhost:44321/hub")
            .Build();

await connection.StartAsync();

connection.On<SomeEvent>("HubMethodName", (ev) => Console.WriteLine("EventHandler"))
Run Code Online (Sandbox Code Playgroud)

我想在事件处理程序中进行一些异步工作,但是对我来说,如何立即执行并不太明显,因为大多数重载都期望an Action。使用async void作品,但我不确定这是一个好主意。另外,签名有一个过载,On(string methodName, Type[] parameters, Func<object[], Task>) handler)这是有希望的,但是我想我会期望带有的过载On<T>(string methodName, Func<T, Task> handler)。我可以自己创建带有该签名的扩展方法,但是当它不存在时,我想我可能已经错过了一些重要的事情吗?

Gab*_*uci 1

方法的问题async void在于,如果存在未处理的异常,它们可能会使您的应用程序崩溃。请阅读此处此处

这些文章确实说只有async void在发生事件时才允许这样做,而这些就是我们正在讨论的事件。但异常确实可能导致整个应用程序崩溃。因此,如果您打算这样做,请确保在可能抛出异常的任何地方都有/块(但是,当您尝试记录它时,块内仍然可能发生异常)。trycatchcatch

async void方法也可能导致意外行为,因为调用它的代码不会等待它完成后再开始执行其他操作。

请记住,这样做的好处await是 ASP.NET 可以先去做其他事情,然后再回来处理其余的代码。通常这很好。但在这种特定情况下,这可能意味着两个(或更多)传入消息可以同时得到处理,并且哪个消息先完成是一个折腾(第一个完成处理的消息可能不是第一个传入的消息) )。尽管这对于您的情况可能重要也可能不重要。

您最好将其设为同步,然后等待无法同步的内容:

connection.On<SomeEvent>("HubMethodName", HandleHubMethodName);
Run Code Online (Sandbox Code Playgroud)
private void HandleHubMethodName(ev) {
    SomeAwaitableThing().GetAwaiter().GetResult();
}
Run Code Online (Sandbox Code Playgroud)

请参阅此处此处了解使用.GetAwaiter().GetResult()而不是 的好处.Wait()