سؤال

Let me start with the fact that similar forms of this question have been asked here, yet there are no working examples or useable answers to the subject (that I have been able to find). This post will attempt to provide a more concise example and advance a code block to that end. With reference to the following links that are similar though not conclusive/working examples.

similar link #1 Background worker

similar link #2 Multi Threading in web service

similar link #3 threading in ASP.net

similar link #4 acknowledge quickly but continue processing

Other links:

#1 Async Web service Call

#2 Calling Web Service Async functions from web page

#3 MS ThreadPool.QueueUserWorkItem Method

#4 MS Multithreading Walk Through Forms based

The problem is returning a response to a client consuming a web service so that the client can continue on its way while the web service completes processing tasks. The web service (after authentication) receives a file name from the client that should be retrieved from a distant ftp server. Once the file has been downloaded to the web service hosting server, the client can be released, as the file name was valid and has been copied to the local server.

The web server, after returning a simple 'true' Boolean response to the client, continues to crunch the downloaded file into a database and happily waits for the name of the next file.

The current call is a SOAP message and this is a traditional asmx web service.

Web Service:

<WebService details .....

Public sourceFile As String
Public myData as Boolean = False
    <WebMethod()> _
Public Function fileReady_Log2(ByVal user As String, ByVal PW As String, ByVal fileName As String) As String

    ' This function receives a web service call notifying this server to retrieve a file from a remote ftp server When the file is downloaded it is processed into this servers database.
    '
    ' This routine attempts to process an ASYNC routine to respond to the call and release the caller as soon as possible while continuing processing requirements.

    ' Validation removed for simplicity 
    If authorized Then
    ' Need to retrieve ftp server information and pull down the file and load it to the database.
        ' Call Async function

        sourceFile = filename

        Dim myObject = New ftpThread()
        myObject.SendDataAsync()

        ' Ok, now return the result to client.
        Return myData

        Dim ftpInfo As New ftpFileImport   '  continue with processing the uploaded file.
        results = ftpInfo.retrieveLogFile(fileName, deviceID, usr)


        Return results
    End If
    Return results
End Function

Currently this is the structure of the calling functions. I have tried a number of variations and decided now is a good time to stop and ask for help.

ftpThread.vb

Imports Microsoft.VisualBasic
Imports System.Threading


Public Class ftpThread
    Public Sub SendDataAsync()
        ThreadPool.QueueUserWorkItem(Sub(getFtpFileExists(sourceFile )))
    End Sub
End Class

I am also getting an Expression Expected exception on the word Sub above.

ftp functions This process works synchronously, need it to be asynchronous.

 Public Class ftpFileExistsCheck
      Public Sub getFtpFileExists()

        ' This all works without ASYNC 

           '  Retrieve FTP credentials from DB
           '  Set up ftp request
           '  download the file.

        '  But continuing process to DB at this point causes client to wait.
           myData  = True
     End Sub
 End Class

Thought I could figure this out from all I have read, but I just can't get past setting up the correct coding for ASYNC processing.

هل كانت مفيدة؟

المحلول

In your ASMX service implementation, you should spin up a WCF client and invoke a one way service operation, passing the message straight across. This not only lets you solve your problem but when you can upgrade off of ASMX, you can go directly to the new but still familiar WCF endpoint.

  1. Implement a WCF service that mirrors your existing ASMX methods you need this kind of functionality in
  2. Make each service operation a one way operation
  3. Modify your existing ASMX service to consume the new WCF service and enjoy

Another alternative would be to use Windows Workflow Foundation (WF). WF lets you compensate an activity with the result of some service call. This means your service continues progressing until you need the value from the service, similar to how async and await works. You could create a WCF Workflow Service that represents your existing ASMX service and make the workflow a one way service operation, then fire off the entire workflow and dequeue work items in the workflow until completion or some expiration time or whatever criteria you need to indicate the workflow should stop expecting more work.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top