SignalR .Net客户端 - 如何同步和异步调用

时间:2014-01-15 10:03:35

标签: signalr signalr.client

我正在使用.Net客户端(而不是javascript)学习SignalR,并且希望澄清如何以同步或异步方式调用集线器代理方法。

没有返回值的方法

到目前为止,我一直在做这样的事情: -

myHubProxy.Invoke("DoSomething");

我发现这是异步的,这很好,因为它实际上是“即发即忘”,并且不需要等待返回值。但有几个问题: -

  1. 在try..catch块中包装Invoke是否有任何影响,特别是它是异步的?我可能想知道呼叫是否失败。
  2. 是否有任何情况需要调用不会同步返回值的方法?我已经看到了提到的.Wait()方法,但我想不出你为什么要这样做。
  3. 方法 返回值

    到目前为止,我一直在使用Result属性,例如: -

    var returnValue = myHubProxy.Invoke<string>("DoSomething").Result;
    Console.WriteLine(returnValue);
    

    我假设这个工作同步 - 毕竟,在返回结果之前,它无法进入下一行。但是我如何异步调用这样的方法呢?是否有可能指定一个回调方法,或者我现在应该真的使用async / await(这是我承认仍然没有学到的东西)?

2 个答案:

答案 0 :(得分:5)

如果要编写异步代码,则应使用async / awaitI have an intro on my blog with a number of followup resources at the end.

当您启动异步操作(例如Invoke)时,您将获得一个任务。 Task类型用于没有返回值的异步操作,Task<T>用于具有返回值的异步操作。这些任务类型可以在操作完成时指示您的代码,以及它是否成功完成或出错。

虽然您可以使用Task.WaitTask<T>.Result,但我不建议使用它们。例如,它们将AggregateException中的任何异常包装起来,这使得您的错误处理代码更加繁琐。使用await要容易得多,而不是这样做。同样,您可以使用ContinueWith注册回调,但我不推荐它;你需要了解很多关于任务调度程序以及正确使用它的东西。使用await要容易得多,默认情况下(最可能)是正确的。

答案 1 :(得分:0)

.Result属性返回异步任务,因此服务器请求仍然执行异步。 没有理由在调用期间保持一个线程,这就是你使用异步的原因。

如果您在GUI线程上触发调用,则更重要的是它是异步的,否则GUI将在调用完成时不响应

1)如果你想尝试catch块来实际捕获服务器故障,Yuo需要使用await关键字。像

try
{
    var foo = await proxy.Invoke<string>("Bar");
}
catch (Exception ex)
{
    //act on error
}

2)我认为你会问它是否有任何理由称它为异步?就像我说的那样,你不想在发出请求时阻止任何线程