views:

486

answers:

5

We have a service to update customer information to server. One service call takes around few seconds, which is normal.

Now we have a new page where at one instance around 35-50 Costumers information can be updated. Changing service interface to accept all customers together is out of question at this point.

I need to call a method (say "ProcessCustomerInfo"), which will loop through customers information and call web service 35-50 times. Calling service asynchronously is not of much use.

I need to call the method "ProcessCustomerInfo" asynchronously. I am trying to use RegisterAsyncTask for this. There are various examples available on web, but the problem is after initiating this call if I move away from this page, the processing stops.

Is it possible to implement Fire and Forget method call so that user can move away (Redirect to another page) from the page without stopping method processing?

A: 

I believe the issue is the fact is your web service is expecting a client to return the response to, that the service call itself is not a one way communication.

If you're using WCF for your webservices look at http://moustafa-arafa.blogspot.com/2007/08/oneway-operation-in-wcf.html for making a one way service call.

My two cents: IMO whoever put the construct on you that you're not able to alter the service interface to add a new service method is the one making unreasonable demands. Even if your service is a publicly consumed API adding a new service method shouldn't impact any existing consumers.

Chris Marisic
Problem is not getting response from the service but calling service 50 times. One-way call to service will not help me here, I need to find way to call the method which is actually making service calls.......Changing interface is a problem as this service is exposed by another vendor and they are not willing to change it at this moment.
BinaryHacker
The one way service call would fix your problems, you wouldn't need to fire them all asynchronously as they'd open their request fire the data and close the connection that when you hit submit or whatever your page does that it just finishes in a second and is done. however if you don't own the service you can't change it to be 1 way.
Chris Marisic
A: 

Sure you can.

Restuta
Thanks. This is the method i am trying currently. But issue is movie away from the page. If user clicks on any of the link to move on to another page, the asynch processing also stops.
BinaryHacker
@ExpertSoul - it seems unlikely that the asynch processing is stopping when you change pages, because according to the document Restuta linked to, the asynchronous tasks must complete before the page is rendered (before it is delivered to the browser). Did you remember to add a Page directive with an Async="true" attribute or set the Page's AsyncMode property to "true"? Something tells me that your asynchronous tasks may not be executing at all.
Chris Shouts
@paper1337 - just verified it again. With Redirection statement , the "OnBegin" method is called but operations times out so it comes back to the page. But OnBegin is processed till end. With a redirection statement (which i placed just after async method call) "OnBegin" never gets called. Also, though it is mentioned everywhere to specify property Async="true", I didn't see any differece in processing with or without it.
BinaryHacker
+1  A: 

Details on: http://www.codeproject.com/KB/cs/AsyncMethodInvocation.aspx

Basically you can create a delegate which points to the method you want to run asynchronously and then kick it off with BeginInvoke.

// Declare the delegate - name it whatever you would like
public delegate void ProcessCustomerInfoDelegate();

// Instantiate the delegate and kick it off with BeginInvoke
ProcessCustomerInfoDelegate d = new ProcessCustomerInfoDelegate(ProcessCustomerInfo); 
simpleDelegate.BeginInvoke(null, null);

// The method which will run Asynchronously
void ProcessCustomerInfo()
{
   // this is where you can call your webservice 50 times
}
Joel
Thanks Joel! I saw this method earlier but ignored as MethodInvoker is part of System.Windows.Form. It seems to be working fine with Redirection, though I need to do more testing. But should I be using this method for ASP.NET? Or is there any Web alternative to this?
BinaryHacker
Oops yeah, sorry about that. It would work fine with ASP.NET, but would be a shame to have to include System.Windows.Form in your project if you don't have to. Instead you can create your own delegate and use that instead of MethodInvoker. I've updated the code sample above.
Joel
MethodInvoke is just a delegate already created for you with no parameters or return values so that you don't have to take the time to create your own. ProcessCustomerInfoDelegate that we just created works exactly the same way.
Joel
There has been some discussion on whether calling BeginInvoke without EndInvoke is a bad idea - mostly because the not calling the EndInvoke operation on some delegates can result in a memory leak. Might I suggest ThreadPool.QueueUserWorkItem(cb=>ProcessCustomerInfo()) instead
Chris
A: 

This was something I whipped just to do that...


    public class DoAsAsync
    {
        private Action action;
        private bool ended;

        public DoAsAsync(Action action)
        {
            this.action = action;
        }

        public void Execute()
        {
            action.BeginInvoke(new AsyncCallback(End), null);
        }

        private void End(IAsyncResult result)
        {
            if (ended)
                return;

            try
            {
                ((Action)((AsyncResult)result).AsyncDelegate).EndInvoke(result);
            }
            catch
            {
                /* do something */
            }
            finally
            {
                ended = true;
            }
        }
    }

And then

    new DoAsAsync(ProcessCustomerInfo).Execute();

Also need to set the Async property in the Page directive <%@ Page Async="true" %>

I'm not sure exactly how reliable this is, however it did work for what I needed it for. Wrote this maybe a year ago.

Dave
A: 

I think what you are wanting is a true background thread:

Safely running background threads in ASP.NET 2.0

Creating a Background Thread to Log IP Information

rick schott