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

时间:2018-06-08 09:23:45

标签: signalr.client

信号器的.NET核心客户端有一个HubConnection类,可以通过以下方式使用。

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

await connection.StartAsync();

connection.On<SomeEvent>("HubMethodName", (ev) => Console.WriteLine("EventHandler"))

我想在事件处理程序中做一些异步工作,但是对我来说并不是很明显,因为大多数重载都是Action。使用async void有效,但我不确定这是个好主意。此外,签名On(string methodName, Type[] parameters, Func<object[], Task>) handler)的重载很有希望,但我想我会期望On<T>(string methodName, Func<T, Task> handler)。我可以自己制作一个带有该签名的扩展方法,但是当它不是一开始的时候,我认为我可能错过了一些重要的东西?

1 个答案:

答案 0 :(得分:0)

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

这些文章确实说,由于事件的缘故,async void仅被允许使用 ,而这些是我们正在谈论的事件。但是,仍然可以例外的是,异常可能会使您的整个应用崩溃。因此,如果要执行此操作,请确保在可能会引发异常的任何地方有try / catch块(但是,尝试执行操作时,catch块中可能会发生异常)记录下来。)

但是async void方法也可能导致意外行为,因为调用它的代码没有在开始执行其他操作之前等待它完成。

请记住,await的好处是ASP.NET可以关闭并执行其他操作,稍后再返回其余代码。通常那很好。但是在这种特定情况下,这可能意味着可以同时处理两条(或更多条)传入的消息,并且要对先完成的消息进行一次折腾(完成处理的第一个消息可能不是传入的第一个) )。尽管这可能与您的情况无关紧要。

您最好让它同步,然后等待您无法同步的内容:

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

有关使用.GetAwaiter().GetResult()而非.Wait()的好处,请参见herehere