0

I have a long running operation you might read in couple of my another questions (for your reference here is first and second).

In the beginning of whole deal, project expose a form in which user should specify all necessary information about XML file and upload XML file itself. In that method all user input data caught and went to an WCF service that handles such king of files. Controller got only task id of such processing. Then user got redirected to progress bar page and periodically retrieves status of task completeness, refreshes the progress bar.

So here is my issue comes. When processing of XML file if over, how can I get results back and show them to user?

I know that HTTP is stateless protocol but there is cookie mechanism that could help in this situation. Of course, I may just save processing results to some temporary place, like a static class in WCF server, but there is a high load on service, so it will eat all of supplied memory.

In other words, I would like to pass task to WCF service (using netNamedPipeBinding) and receive results back as fast as it really possible. I want to escape temporary saving result to some buffer and wait until client will gather it back.


As far as I go is using temporary buffer not on service side but at client's:

using (XmlProcessingServiceClient client = new XmlProcessingServiceClient())
{
    client.AnalyzeXmlAsync(new Task { fileName = filePath, id = tid });
    client.AnalyzeXmlCompleted += (sender, e) =>
    {
        System.Web.HttpContext.Current.Application.Lock();
        // here is I just use single place for all clients. I know it is not right, it is just for illustrating purposes.
        System.Web.HttpContext.Current.Application["Result"] = e;
        System.Web.HttpContext.Current.Application.UnLock();
    };
}
Community
  • 1
  • 1
kseen
  • 359
  • 8
  • 56
  • 104

4 Answers4

3

I suggest you to use a SignalR hub to address your problem. You have a way to call a method on the client directly to notify the operation completed. And this happen without having to deal with the actual infrastructure trouble there is in implementing such strategies. Plus SignalR plugs easily in an asp.net MVC application.

Felice Pollano
  • 32,832
  • 9
  • 75
  • 115
0

To be honest I didn't really get the part about the wcf server and stuff, but I think I can give you more of an abstract answer. To be sure:

  1. You have a form with some fields + file upload
  2. The user fills in the form and supplies an XML file
  3. You send the XML file to an WFC services which procress it
  4. Show in the mean time a progress bar which updates
  5. After completion show the results

If this is not want you want or this is not what your question is about you can skip my answer, otherwise read on.

Before we begin: Step 3 is a bit ambiguous: It could mean that we send the data to the service and wait for it to return the result or that we send the data to the service and we don´t wait for it to return the result.

Situation 1:

  1. Create in a view the form with all the required fields
  2. Create an action in your controller which handles the postback.
  3. The action will send the data to the service and when the service returns the result, your action will render a view with the result.
  4. On the submit button you add an javascript on click event. This will trigger an ajax call to some server side code which will return the progress.
  5. The javascript shows some sort of status bar with the correct progress and repeats itself every x seconds
  6. When the controller finishes it will show the result

Situation 2:

  1. -
  2. -
  3. After sending the data to the service the controller shows a view with the progress bar.
  4. We add an javascript event on document ready which checks the status of the xml file and updates a progressbar. (same as the onclick event in step 4 in situation 1)
  5. When the progressbar reaches 100% it will redirect to a different page which shows the results

Does this answer your question?

Best regards,

BHD

Maarten Kieft
  • 6,806
  • 3
  • 29
  • 34
0

netNamedPipeBinding will not work for cross-machine communication if this is what you have in mind.

If you want to host our service on IIS then you will need one of the bindings that use HTTP as their transport protocol. Have a look at the duplex services that allow both endpoints to send messages. This way the server can send messages to the client anytime it wishes to. You could created a callback interface for progress reporting. If the task is going to take a considerable amount of time to complete, then the overhead of the progress reporting through HTTP might be ok.

Also have a look at Building and Accessing Duplex Services if you want to use a duplex communication over HTTP with Silverlight (PollingDuplexHttpBinding).

Finally you could look for a Comet implementation for ASP.NET. In CodeProject you will at least a couple (CometAsync and PokeIn).

Panos Rontogiannis
  • 4,154
  • 1
  • 24
  • 29
0

I'm not sure if this is the best solution but I was able to do something similar. This was the general setup:

  1. Controller A initialized a new class with the parameters for the action to be performed and passed the user's session object
  2. The new class called a method in a background thread which updated the user's session as it progressed
  3. Controller B had json methods that when called by client side javascript, checked the user's session data and returned the latest progress.

This thread states that using the session object in such a way is bad but I'm sure you can do something similar with a thread safe storage method like sql or a temp file.

Community
  • 1
  • 1
James Santiago
  • 2,883
  • 4
  • 22
  • 29