views:

387

answers:

3

I have an ASP.NET webservice (.asmx) with a simple method that reads something from the DB with a sync call (ExecuteReader) and returns the result. There is any way to optimize the Thread Pool usage (ie. by calling an async call (BeginExecuteReader)) without changing the method's signature?

The intention is to not block a thread pool thread while the database operation is in progress; it is not the intention to speed things up by doing multiple operations in parallel.

A: 

I don't see how this would work, when a request comes in for your webservice, a thread from the pool is going to be allocated to process the request, if you make an async call from that thread then your request thread ends and the client would not get any result back.

Short Answer is No. People only seem to be reading this line and downvoting :) The user is asking if we can do an async call from inside a sync webservice call, which is certainly possible by using WaitHandles but does not make sense in the user's specific case.

Sijin
http://msdn.microsoft.com/en-us/magazine/cc163725.aspx for how to do this with Pages. Probably not possible with web services but not for the stated reason.
Aleris
I don't understand the downvoting either.
Jader Dias
John Saunders is right. When you create the Begin* and End* methods, only the * method is exposed. It is transparent to the outside world.
Jader Dias
+2  A: 

With the specific use-case that you provide, with a single async call, it would not be worth it, but, yes, you can invoke async calls from a web service:

[WebMethod]
public SomeResult SynchronousMethod() {
    IAsyncResult someWork = BeginSomeAsyncWork();
    IAsyncResult otherWork = BeginOtherAsyncWork();
    WaitHandle[] all = new WaitHandle[] { someWork.AsyncWaitHandle, otherWork.AsyncWaitHandle };
    // TODO: Do some synchronous work here, if you need to 
    WaitHandle.WaitAll(all); /* this is the important part, it waits for all of the async work to be complete */
   var someWorkResult = EndSomeAsyncWork(someWork);
   var otherWorkResult = EndSomeAsyncWork(otherWork);
   // TODO: Process the results from the async work
   // TODO: Return data to the client
}

The important thing here is the WaitHandle.WaitAll, which will block until all of the async work is complete. If you can process the results individually, you could use WaitHandle.WaitAny instead, but the code gets more complicated, and is a bit out of the scope of the question.

Alex Lyman
Okay. Now I understand Henk's answer.
Jader Dias
+3  A: 

Actually, the answer is yes. See Asynchronous XML Web Service Methods.aspx).

Although you create an async web method with Begin* and End* methods, .NET will only create a single operation in the WSDL. This is obvious if you think about it - what would a Java client do with an IAsyncResult?

The client can call the operation synchronously or asynchronously.

John Saunders
I think what Jader is asking is to make an async call from inside a sync webservice call.
Sijin
I had to test myself to see if it was true, and it is! Congratulations!
Jader Dias
@Sijin: No, he really wanted an asynchronous web service, but thought that meant exposing Begin* and End* as operations to the client. I showed him that it doeds not.
John Saunders