Question

I'm learning SignalR using the .Net client (not javascript), and was hoping for some clarification on how to invoke hub proxy methods in a synchronous or asynchronous manner.

Method with no return value

So far I've been doing something like this:-

myHubProxy.Invoke("DoSomething");

I've found this to be asynchronous, which is fine as it's effectively "fire-and-forget" and doesn't need to wait for a return value. A couple of questions though:-

  1. Are there any implications with wrapping the Invoke in a try..catch block, particularly with it being asynchronous? I might want to know if the call failed.
  2. Are there any scenarios where you would want to call a method that doesn't return a value synchronously? I've seen the .Wait() method mentioned, but I can't think why you would want to do this.

Method with return value

So far I've been using the Result property, e.g.:-

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

I'm assuming this works synchronously - after all, it couldn't proceed to the next line until a result had been returned. But how do I invoke such a method asynchronously? Is it possible to specify a callback method, or should I really be using async/await these days (something I confess to still not learning about)?

Was it helpful?

Solution

If you want to write asynchronous code, then you should use async/await. I have an intro on my blog with a number of followup resources at the end.

When you start an asynchronous operation (e.g., Invoke), then you get a task back. The Task type is used for asynchronous operations without a return value, and Task<T> is used for asynchronous operations with a return value. These task types can indicate to your code when the operation completes and whether it completed successfully or with error.

Although you can use Task.Wait and Task<T>.Result, I don't recommend them. For one, they wrap any exceptions in an AggregateException, which make your error handling code more cumbersome. It's far easier to use await, which does not do this wrapping. Similarly, you can register a callback using ContinueWith, but I don't recommend it; you need to understand a lot about task schedulers and whatnot to use it correctly. It's far easier to use await, which does the (most likely) correct thing by default.

OTHER TIPS

The .Result property returns a async Task, so the server requests is still performed async. There is not reason to hold up a thread for the duration of the call thats why you use async.

If you fire the call on the GUI thread its even more important todo it async because otherwise the GUI will not respond while the call is done

1) Yuo need to use the await keyword if you want try catch blocks to actually catch server faults. Like

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

2) I think you ment to ask if its any reason to call it async? And yes like I said, you do not want to block any threads while the request is being made

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top