我正在使用.Net客户端(而不是javascript)学习SignalR,并且希望澄清如何以同步或异步方式调用集线器代理方法。
没有返回值的方法
到目前为止,我一直在做这样的事情: -
myHubProxy.Invoke("DoSomething");
我发现这是异步的,这很好,因为它实际上是“即发即忘”,并且不需要等待返回值。但有几个问题: -
方法 返回值
到目前为止,我一直在使用Result
属性,例如: -
var returnValue = myHubProxy.Invoke<string>("DoSomething").Result;
Console.WriteLine(returnValue);
我假设这个工作同步 - 毕竟,在返回结果之前,它无法进入下一行。但是我如何异步调用这样的方法呢?是否有可能指定一个回调方法,或者我现在应该真的使用async / await(这是我承认仍然没有学到的东西)?
答案 0 :(得分:5)
如果要编写异步代码,则应使用async
/ await
。 I have an intro on my blog with a number of followup resources at the end.
当您启动异步操作(例如Invoke
)时,您将获得一个任务。 Task
类型用于没有返回值的异步操作,Task<T>
用于具有返回值的异步操作。这些任务类型可以在操作完成时指示您的代码,以及它是否成功完成或出错。
虽然您可以使用Task.Wait
和Task<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)我认为你会问它是否有任何理由称它为异步?就像我说的那样,你不想在发出请求时阻止任何线程