none
Calling a webservice method asynchronously RRS feed

  • Question

  • Hello,

    I need to call the Register() method on a Web service asynchronously (using C#). The implementation of the actual Register method in the Web service does not return any value. But it throws an exception if the method fails. Given this, does the following code look ok please?
    public void RegisterProduct(string productName)
    {
        await RegisterProductAsync();
    }

    private async static Task RegisterProductAsync(string productName)
    {
        try
        {
             await myWebService.Register(productName);  
        }
        catch(Exception ex)
        {
            LogException(ex);
        }
    }

    Thanks.

    Wednesday, August 16, 2017 1:48 PM

All replies

  • Wednesday, August 16, 2017 2:24 PM
  • Hello,

    I need to call the Register() method on a Web service asynchronously (using C#). The implementation of the actual Register method in the Web service does not return any value. But it throws an exception if the method fails. Given this, does the following code look ok please?
    public void RegisterProduct(string productName)
    {
        await RegisterProductAsync();
    }

    private async static Task RegisterProductAsync(string productName)
    {
        try
        {
             await myWebService.Register(productName);  
        }
        catch(Exception ex)
        {
            LogException(ex);
        }
    }

    Thanks.

    Wednesday, August 16, 2017 2:33 PM
  • If you're calling a WCF service then you're likely using a service reference as that is how VS will want to generate the code. In this case you can rerun the configuration for the reference. One of the options is to generate async methods. Check that box and let VS auto-generate the correct code for you.

    But if you really wanted to write your own then your code is not correct nor would it even compile. You can only await on a Task-returning method. You need to wrap it in Task.Run to get the async behavior. But your exception handling isn't correct either. Tasks will return AggregateException or TaskCanceledException. You need to ignore the second one and unwrap the first one to get to the exception that occurred (noting that the cancel can come through via AggregateException as well).

    private async Task RegisterProductAsync ( string productName )
    {
       try
       {
          await Task.Run(() => myWebService.Register(productName));
       } catch (TaskCanceledException)
       {
          //Ignore?
       } catch (AggregateException e)
       {
          //Do you expect more than one exception?
          var inner = e.InnerException;
          if (!(inner as TaskCanceledException))
             LogException(inner);
    
          //Don't bubble the aggregate exception up
          throw inner;
       } catch (Exception e)
       {
          LogException(e);
    
          throw;
       };
    }
    We actually created some extension methods for Task/Task<T> that wrap the try catch logic so that we can convert normally async methods to sync. You might consider doing the same if you intend to call sync methods as async a lot.

    Michael Taylor
    http://www.michaeltaylorp3.net

    Wednesday, August 16, 2017 5:18 PM
    Moderator
  • Hi Ani2000,

    For detail implementation of the first suggestion from CoolDadTx, you could follow below steps.

    1. Create a WCF Service with below operation.

        public class Service1 : IService1
        {
            public void DoSomeThing(string productName)
            {
                if (productName == "")
                {
                    throw new FaultException("Product Name could not be Null");
                }
                System.Diagnostics.Debug.WriteLine(productName);
            }        
        }
    

    2. Add Service Reference by checking Allow generation of asynchronous operations and select Generate task-based operations

    3. Call it from client side

            private async void WCFAsync_Click(object sender, EventArgs e)
            {
                await RegisterProductAsync("");
            }
            private async static Task RegisterProductAsync(string productName)
            {
                try
                {
                    WCFAsyncSvc.Service1Client client = new WCFAsyncSvc.Service1Client();
    
                    await client.DoSomeThingAsync(productName);
                }
                catch (Exception ex)
                {
                    
                }
            }

    I suggest you pay attention to exception handling in service side by FaultException, otherwise, you will not get detail exception description.

    Best Regards,

    Edward


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, August 17, 2017 2:51 AM