Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Execute web service method and return immediately

C# ASP.NET 3.5

Is it possible to "fire and forget" a method in a web service that is not asynchronous or one-way?

There is a method that returns a value (after some processing), which I don't need. It is used by another group (who wrote the service). Basically, it just notifies that user x did action y. I just need to call the method and move on without waiting for the result.

I tried using a BackgroundWorker() with RunWorkerAsync, but the method does not fire for some reason. I cannot change the web service method as I have no access to their code. Should I be using BackgroundWorker, Invoke, ThreadPool, something else? I don't need the result returned, and I don't need to know if it fails. Basically, call the method, and if it works, great. If not, I don't want to stop or slow processing down.

public static void Test()
{
    var worker = new BackgroundWorker();
    worker.DoWork += Test2;
    worker.RunWorkerAsync(new object[] {12345, "test"});
}

private static void Test2(object sender, DoWorkEventArgs e)
{
   // Write to log that we got into the method - does not
   object[] args = e.Argument as object[];
   int num = Convert.ToInt32(args[0]);
   string name = (string)args[1];
   // call web service method here....
}
like image 320
Outside the Box Developer Avatar asked Sep 21 '26 08:09

Outside the Box Developer


2 Answers

Intsead of using Background Worker you can try the following

    public static void Test()
    {
        System.Threading.ThreadPool.QueueUserWorkItem(delegate
        {
            Test2(new object[] { 12345, "test" });
        });
    }

    private static void Test2(object data)
    {
        // Write to log that we got into the method - does not
        object[] args = data as object[];
        int num = Convert.ToInt32(args[0]);
        string name = (string)args[1];
        // call web service method here....
    }
like image 162
Patrick D'Souza Avatar answered Sep 22 '26 22:09

Patrick D'Souza


The feature that is requested, by definition IS WCF OneWay. It is impossible to implement the required behavior completely client-side.

IIS by default (a common host of WCF services) is allowed to kill any process that was kicked off by a closed connection. This means that the client must stay connected for the duration of the process (which in effect means waiting for the result). Additionally it is possible the request can timeout and the "fire and forget" process is killed off.

If you only want to reduce the resources taken up at the client to the minimum whilst the request is in flight I would run the request asynchronously. If you only have access to .net<=4.0 then the easiest way to do this is to generate the async calls (I mean APM async and NOT async/await/TPL async) using the "add service reference" option and tick the "generate async methods" option.

You would have to also learn the APM programming model (which is pretty nasty).

Alternatively you could run the WCF call on a separate Thread. But note, this uses significant additional resources.

like image 42
Aron Avatar answered Sep 22 '26 22:09

Aron