.netweb-servicesrequest-queueing

.NET Best approach to implementing client/server queuing model with external app?


Here is the spec:

  1. Multiple clients using a WPF winforms application on their local machines
  2. Clients initiate requests to the server to execute a simulation. This initiation should probably be via a web service but other suggestions are welcome
  3. Requests are queued on the server
  4. Server sends out sequential requests to the simulation model via a web service.
  5. Server informs client that simulation is complete

An additional requirement is to have a client cancel a request they have previously made. Note that we dont have to worry about sending too much data down the pipe, we are only sending confirmation that a particular simulation run completed (or failed)

To begin with I thought I could do all of this with a single asmx web service, but now I think that might be unwieldy. WCF seems like another option, but I am not familiar with it and it seems far more complicated than the functionality I need.

Any ideas?


Solution

  • Client: To get the completion notification you will need to use the async design pattern when calling the web service from the client. If you use "add web reference" to create the client proxy the async pattern methods are generated for you. See: "Access Web Services Asynchronously in .NET Design Patterns".

    Server: A vanilla .Net 2.0 asmx web service can queue the incoming calls for serial processing on the server. You can build a simple dispatcher using the BackgroundWorker class. The dispatcher takes each incoming request and assigns it to a background thread. To serialize the threads have the worker method place a lock around the simulation call. See this example of using BackgroundWorker threads.

    Cancellation: To handle cancellation have the server return a unique id with its response to the client request and also insert the id and the associated background workworker reference into a dictionary. A CancelSimulation method on the web service accepts the id, looks up the BackgroundWorker ref in the dictionary and calls its CancelAsync method. Remove the dictionary entry when the task completes or is cancelled. The dictionary needs to be shared by all web service calls so it should be static/Shared. Fortunately, a static dictionary is thread-safe.