locked
Calling Long Running Web Service from Web Api RRS feed

  • Question

  • User1122355199 posted

    Hello everyone and thanks for your help in advance.  I have a WebApi that is called from a web page that inserts data into a SQL table.  I now need to add a process that contacts an outside web service to obtain additional information.  The API does not need to wait for the return of data from the web service, but does need to be called from the API.  When incorporated into the API, the process causes a hang (about 15 seconds) that is unnecessary.  I'm not sure how to attack this problem.  Any help would be appreciated.

    Thursday, September 29, 2016 6:41 PM

Answers

  • User1122355199 posted

    Thanks for the response.  I moved the closing of the jQuery dialog outside of the success function, so now the box closes properly.  However, I still have a problem in that the page also uses SignalR to dynamically update and still appears to hang.  Let me explain a little more in depth of what the page does.  It is an online appointment scheduler that allows the user to add appointments.  Once the appointment is added, it should fire a SQL Notification to update the page and show the added appointment.  What I want to accomplish is that, when an appointment is added, I want to set off a long-running task that calls a webservice that retrieves more information about the appointment.  The calling page does not need to wait for the long-running task to finish, so it can operate in a completely separate thread.  My thinking is that the code used above should do that, but it doesn't seem to release the calling api.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, October 14, 2016 1:26 PM

All replies

  • User36583972 posted

    Hi kmcnet,

    When incorporated into the API, the process causes a hang (about 15 seconds) that is unnecessary. 

    Asynchrony is essential for activities that are potentially blocking, such as access to a web resource sometimes is slow or delayed. In an asynchronous process, the application can continue with other work that doesn't depend on the web resource until the potentially blocking task finishes.

    So, I suggest you can try to use async await in your Web API when your contacts an outside web service to obtain additional information.

    Asynchronous Controller of Web API 2 With Entity Framework 6: Put and Delete Method:

    http://www.c-sharpcorner.com/UploadFile/dacca2/asynchronous-controller-of-web-api-2-with-entity-framework-6622/

    Asynchronous Programming with async and await (C#):

    https://msdn.microsoft.com/en-us/library/mt674882.aspx

    Best Regards,

    Yohann Lu

    Friday, September 30, 2016 2:34 AM
  • User1122355199 posted

    Thanks for the response.  I do understand the need for an async call but am having problems implementing it.  Here is my code so far.  The api looks like:

        <HttpPost>
        <Route("api/AddAppointment")>
        Public Sub AddAppointment(<FromBody()> ByVal model As Appointment)
    
            ' Do some stuff to parse the data sent and add it to a database
    
            '************************************************************************************
            ' Now invoke the class library that makes the call to the web service - this si the long running service
            '************************************************************************************
    
                Dim EligibilityManager As New EDI_Transaction_Library.Build270Request()
                Dim RequestFile As String = EligibilityManager.BuildRequestByMRNumber(MRNumber, InsuranceName)
                Dim RTRequest As New EDI_Transaction_Library.FLMMIS_Realtime_Request(RequestFile)
                Dim ResponseFile As String = RTRequest.FLMMISRealtimeResponse
    
        End Sub

    Now my thinking is that I need another function:

    Private Async Function GetEligibility(ByVal MRNumber As String, ByVal Insurance As String) As Task(Of Integer)
    
    End Function

    and place the call to the webservice in this, but I don't know where the await should be placed and my understanding is that without the await, it won't be async.    The calling function is not immediately needed in the calling function.  Any help would be appreciated.

    Friday, September 30, 2016 9:51 PM
  • User36583972 posted

    Hi  kmcnet,

    but I don't know where the await should be placed and my understanding is that without the await, it won't be async.   

    You can use Task.Run(() => Method()). You can refer the following code.

    VB:

      <AllowAnonymous> _
          <HttpGet> _
          Public Function testasync() As Task(Of Integer)
        	     Return Await Task.Run(Function() TestASS())
           End Function
    
           Private Function TestASS() As Integer
    
               Dim EligibilityManager As New EDI_Transaction_Library.Build270Request()
                Dim RequestFile As String = EligibilityManager.BuildRequestByMRNumber(MRNumber, InsuranceName)
                Dim RTRequest As New EDI_Transaction_Library.FLMMIS_Realtime_Request(RequestFile)
                Dim ResponseFile As String = RTRequest.FLMMISRealtimeResponse
    	 Return 1
    
           End Function

    C#:

      [AllowAnonymous]
            [HttpGet]
            public async Task<int> testasync()
            {
                return await Task.Run(() => TestASS());
            }
    
            private int TestASS()
            {
                return 1;
            }

    Best Regards,

    Yohann Lu

    Monday, October 3, 2016 5:35 AM
  • User1122355199 posted

    Thanks for the response, but unfortunately, this doesn't seem to work.  Here is my code:

        <HttpPost>
        <Route("api/InsertAppointment")>
        Public Sub Insert(<FromBody()> ByVal model As Appointment)
    
            ' Parse posted values
    
            ' Insert values to database
    
            TestASS(MRNumber)
    
        End Sub
    
        Public Async Function testasync(ByVal MRNumber As String) As Task(Of Integer)
            Return Await Task.Run(Function() TestASS(MRNumber))
        End Function
    
        Private Function TestASS(ByVal MRNumber As String) As Integer
    
           ' Call the web service and get the response
    
            Dim EligibilityManager As New EDI_Transaction_Library.Build270Request()
            Dim RequestFile As String = EligibilityManager.BuildRequestByMRNumber(MRNumber, Insurance)
            Dim RTRequest As New EDI_Transaction_Library.FLMMIS_Realtime_Request(RequestFile)
            Dim ResponseFile As String = RTRequest.FLMMISRealtimeResponse
    
           ' Write the response to disk
            Try
                Dim file As System.IO.StreamWriter
                file = My.Computer.FileSystem.OpenTextFileWriter(FilePath, True)
                file.WriteLine(ResponseFile)
                file.Close()
    
            Catch ex As Exception
    
            End Try
    
            'Now Parse the response file into a database for later consumption
            Try
                Dim EDIParser As New EDI_Transaction_Library.Parse271Response
                EDIParser.ParseResponseFile(FilePath)
    
            Catch ex As Exception
    
            End Try
    
    
            Return 1
    
        End Function

    However, the initial jQuery call to the api hangs for several seconds causing user confusion.  The hang does not occur when I do not call the function for the webservice.  Basically, it appears the calling application waits until all the functions complete.

    Tuesday, October 4, 2016 12:58 AM
  • User1771544211 posted

    Hi kmcnet,

    However, the initial jQuery call to the api hangs for several seconds causing user confusion.  The hang does not occur when I do not call the function for the webservice.  Basically, it appears the calling application waits until all the functions complete.

    If you call something on ajax success like code below, it will wait until the function which the ajax calls to complete and return success. I guess that's why your client side still hangs for several seconds.

    ajax({
        type: "POST",
        url: url,
        data: jsonData,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function //If you call function here, this function will be fired until the request succeed
        , error: onFailure
    });

    You can call the function outside if the ajax() if you don't want to wait.

    Best Regards,

    Jean

    Friday, October 14, 2016 6:55 AM
  • User1122355199 posted

    Thanks for the response.  I moved the closing of the jQuery dialog outside of the success function, so now the box closes properly.  However, I still have a problem in that the page also uses SignalR to dynamically update and still appears to hang.  Let me explain a little more in depth of what the page does.  It is an online appointment scheduler that allows the user to add appointments.  Once the appointment is added, it should fire a SQL Notification to update the page and show the added appointment.  What I want to accomplish is that, when an appointment is added, I want to set off a long-running task that calls a webservice that retrieves more information about the appointment.  The calling page does not need to wait for the long-running task to finish, so it can operate in a completely separate thread.  My thinking is that the code used above should do that, but it doesn't seem to release the calling api.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, October 14, 2016 1:26 PM
  • User36583972 posted

    Hi kmcnet,

      However, I still have a problem in that the page also uses SignalR to dynamically update and still appears to hang.

    I suggest you can post a new thread to ASP.NET SignalR forum for suitable help.

    Your understanding and cooperation will be grateful.

    Best Regards,

    Yohann Lu

    Monday, October 17, 2016 3:06 AM