0

So i have started on a uber for 'x' app. Same concept as Uber. And the following code is the code on my Signalr hub. I use signalr to communicate between client and server. So when a client request for help it connects to RequestForHelp. Then the RequestForHelp sends back a request to the right supplier. And depending on what the supplier answers either HelpResponseYes HelpResponseNo is called. I want to make this a async. I want to make the requestforhelp a task. So when i click the request button the program awaits. Any suggestions how you can do that?

public void RequestForHelp(RequestDetails requestDetails, Location customerClientLocation, int customerClientId)
    {
        Customer Customer = Service.CustomerService.GetCustomerById(requestDetails.CustomerId);
        Customer.ClientId = customerClientId;
        Customer.ClientLocation = customerClientLocation;
        requestDetails.Customer = Customer;

        Clients.User(requestDetails.NearestSupplierList.FirstOrDefault().AspNetUserID).requestForHelpInClient(requestDetails);
    }

    public void HelpResponseYes(RequestDetails requestDetails)
    {
        //A supplier is matched
    }

    public void HelpResponseNo(RequestDetails requestDetails)
    {
       //next supplier on the list     

    }

1 Answers1

0

The only reason to use async is if you have something to await. So I'll assume that you will make your requestForHelpInClient asynchronous and return a Task, and you can await that.

It's as easy as this:

public async void RequestForHelp(RequestDetails requestDetails, Location customerClientLocation, int customerClientId)
{
    Customer Customer = Service.CustomerService.GetCustomerById(requestDetails.CustomerId);
    Customer.ClientId = customerClientId;
    Customer.ClientLocation = customerClientLocation;
    requestDetails.Customer = Customer;

    await Clients.User(requestDetails.NearestSupplierList.FirstOrDefault().AspNetUserID).requestForHelpInClient(requestDetails);
}

However, you always have to think hard when you see async void, because:

  1. It can crash your app if an unhandled exception happens (read this and this), so you have to make sure you put try/catch blocks around anything that can throw an exception, and
  2. Whatever calls it cannot wait until it is complete.

I have had trouble myself with using async event handlers with SignalR because of point #2. Because SignalR cannot wait for your async method to complete, it might start processing another request before the first one is finished. That may or may not be a problem for you.

It was a problem for me, so I kept my event handlers synchronous.

Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
  • Yes it is a problem for me to. So what can i do? I want to "disable" (but with a message saying 'request has been sent wait for response' kind of) the client page when a client requests for help until the request has been answerd. Do you have any ideas? –  Nov 13 '19 at 15:57
  • You can use `Clients.Caller.Whatever()` (where `Whatever()` is a client-side method that you have defined) to send a message to whoever initiated the call you are currently processing. You can read about that and the other options [here](https://learn.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server#selecting-which-clients-will-receive-the-rpc). – Gabriel Luci Nov 13 '19 at 16:08