【问题标题】:Async handler in signalr .net core clientSignalr .net 核心客户端中的异步处理程序
【发布时间】:2018-06-08 09:23:45
【问题描述】:

signalr 的 .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&lt;object[], Task&gt;) handler) 有一个过载,这是有希望的,但我想我会期待一个On&lt;T&gt;(string methodName, Func&lt;T, Task&gt; handler)。我可以自己使用该签名创建一个扩展方法,但是当它不存在时,我在想我可能错过了一些重要的事情?

【问题讨论】:

  • 拍得好。我正要提交这个确切的问题。没有回复?尽管全世界都告诉我不要这样做,但我即将走上使用async void 的相同路线。
  • @TheBuzzSaw 最好选择正确的行为而不是可爱的语法。
  • 感谢两年后的回复。我早就处理过这个问题了。

标签: signalr.client


【解决方案1】:

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();
}

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

【讨论】:

    猜你喜欢
    • 2018-02-28
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-20
    • 2018-04-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多