Question

I've got a simple asmx web service that just needs to log some information to a transactional database. However it is timing out for the client. The call to update the database just calls 1 stored procedure and I don't beleive it could be optimized further for better performance. I've been reduced to just logging the run using log4net and then reading the log in by a separate process that updates the database.

I was wondering if there is a better way to do this. I was wondering if there is a way to make my code do something like:

public bool method(...)
{
  LogRun(...)

  Asynchronously call method to insert transaction

  return true;  
}
Was it helpful?

Solution

EDIT: I was wrong about BackgroundWorker. So I chaged it to the Thread version, tested.

If you want the work done asynchronously, you can study how to start another thread.

public class Service1 : System.Web.Services.WebService
{

    [WebMethod]
    public void Log(int foo, int bar)
    {
        Thread a = new Thread(new ThreadStart(delegate()
        {
            // Do some processing here
            // For example, let it sleep for 10 secs
            Thread.Sleep(10000);
        }));
        a.Start();
    }
}

It would take 10 seconds for Log method to finish processing if the Thread.Sleep(10000) line is in the Log method itself. However, with Thread a, The Log method will return immediately after call.

Also note that, there is no easy way to guarantee the calling client if the insert operation is completed or not, with this style of asynchronous call.

OTHER TIPS

One thing you may want to try is Tracing.

If the query cannot be optimized any further you could increase the timeout value for your SQL client assuming you might be using SQL server.

On the client side that consumes the web service, you can use that method asynchronously if you would like the client to continue performing other operations. When the web method is finished it will trigger an event. There is a nice little example you can read here if you think it might help.

While you can look at doing asynchronous operations inside your webmethod, you're working with threads and/or the threadpool inside asp.net, which already has multi-threading operations in play. While technically feasible, you can also inadvertently rob the system of resources as the httpruntime manages resources in serving requests to your service.

Writing to the local log4net file and importing that data in an offline routine is higher availability than real-time logging, asynch or otherwise, since your sql server can be offline and your service is still available. If you don't require sql server for anything other than logging, prefer keeping db operations out of the webmethod.

If it's just a fire-and-forget call for the client, your web service could just add the details to a queue and return to the client. I've used MSMQ to implement something similar to what you're describing. It doesn't fix a database timeout but it does take the error message away from your clients.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top