Search code examples
wcfweb-servicesasynchronouswcf-ria-services

WCF Return Multiple Function Results Asynchronously?


I've been reading up on how to do this but I'm having a hard time getting my head around it.

Synchronous and Asynchronous Operations

WCF: Working with One-Way Calls, Callbacks, An...

My goal is to return results from multiple functions in a Silverlight enabled WCF service as they are discovered.

A general overview of how this service is desired to work is as follows.

User enters a url that has many large csv files listed in hyperlinks. The service gets the initial user entered url, makes a web request of that url, gets the csv file names using regex, service downloads the csv files to server, files are converted to a different format.

Currently all of that works, but no response is shown until the entire operation is done. I would like to provide feedback during each function.

I'm using VB for this app but am fluent in C# if anyone has a code suggestion.

<ServiceContract(Namespace:="http://somemadeupurl")>
<SilverLightFaultBehavior()>              
<AspNetCompatibilityRequirements(RequirementsMode:=
             AspNetCompatibilityRequirementsMode.Allowed)>
Public Class GetCSV

  <OperationContract()>
  Public Function ProcessInitialLink(ByVal strInitialLink As String)
  'download the source html

  'do a webrequest and extract  csv links   
  'since dates are in the filenames I would like to send back most 
  'recent to user here

    Dim strMostRecentCSV As String=SomeRegexMatch
> 'problem here. Would like to return strMostRecentCSV and keep processing
    GetAndConvertBigCSV(strMostRecentCSV)   
    Return strMostRecentCSV
  End Function

  'actually a list but for brevity..
  Private Function GetAndConvertBigCSV(ByVal strMostRecentCSV as string) 
    'do a bunch of downloading
    'call a function to do a bunch of converting
    'call a function to clean up files
  End Function
End Class

If it's done like this it will return strMostRecentCSV but has to wait until GetAndConvertBigCSV is done before returning.

I've tried spawning GetAndConvertBigCSV as a new thread and it works but returns nothing that I can bind to the Silverlight client (e.Result)

At a minimum I would like to provide feedback of the first function Return then have the service continue.

Thanks a million for help.


Solution

  • I would NOT recommend using a polling duplex to solve this business requirement, due to the load it places in the server. What I read was that you have a need to return several files back to the client, and provide feedback to the client as the files are being downloaded.

    As downloading a file does not seem to be an issue (which should be a stream), I think you are asking is how to update the UI, while the files are being downloaded, perhaps capturing how much of the file is actually being downloaded. At the least, you should be updating the UI as each file arrives.

    The latter is easy, simply download the download links to each file on the client, do them one by one, and update the UI between file downloads. That would be a single threaded approach.

    Update the UI while a background thread is executing, is a more complicated approach, but a much better implementation, as the client "feels" that they remain in control while the files are being downloaded. Here is an approach for downloading a file async.

    Remember in SilverLight, you really only have HTTP to transfer information to the application, which cannot do duplex. HTTP long pooling achieves the same result, but connections are left open, and greatly minimize the ability to scale.