Long post.. sorry
I’ve been reading up on this and tried back and forth with different solutions for a couple of days now but I can’t find the most obvious choice for my predicament.
About my situation; I am presenting to the user a page that will contain a couple of different repeaters showing some info based on the result from a couple of webservice calls. I’d like to have the data brought in with an updatepanel (that would be querying the result table once per every two or three seconds until it found results) so I’d actually like to render the page and then when the data is “ready” it gets shown.
The page asks a controller for the info to render and the controller checks in a result table to see if there’s anything to be found. If the specific data is not found it calls a method GetData() in WebServiceName.cs. GetData does not return anything but is supposed to start an async operation that gets the data from the webservice. The controller returns null and UpdatePanel waits for the next query.
When that operation is complete it’ll store the data in it’s relevant place in the db where the controller will find it the next time the page asks for it.
The solution I have in place now is to fire up another thread. I will host the page on a shared webserver and I don’t know if this will cause any problems..
So the current code which resides on page.aspx:
Thread t = new Thread(new ThreadStart(CreateService));
t.Start();
}
void CreateService()
{
ServiceName serviceName = new ServiceName(user, "12345", "MOVING", "Apartment", "5100", "0", "72", "Bill", "rate_total", "1", "103", "serviceHost", "password");
}
At first I thought the solution was to use Begin[Method] and End[Method] but these don’t seem to have been generated. I thought this seemed like a good solution so I was a little frustrated when they didn’t show up.. is there a chance I might have missed a checkbox or something when adding the web references?
I do not want to use the [Method]Async since this stops the page from rendering until [Method]AsyncCompleted gets called from what I’ve understood.
The call I’m going to do is not CPU-intensive, I’m just waiting on a webService sitting on a slow server, so what I understood from this article: http://msdn.microsoft.com/en-us/magazine/cc164128.aspx making the threadpool bigger is not a choice as this will actually impair the performance instead (since I can’t throw in a mountain of hardware).
What do you think is the best solution for my current situation? I don’t really like the current one (only by gut feeling but anyway)
Thanks for reading this awfully long post..
Interesting. Until your question, I wasn’t aware that VS changed from using
Begin/EndtoAsync/Completedwhen adding web references. I assumed that they would also includeBegin/End, but apparently they did not.You state “GetData does not return anything but is supposed to start an async operation that gets the data from the webservice,” so I’m assuming that
GetDataactually blocks until the “async operation” completes. Otherwise, you could just call it synchronously.Anyway, there are easy ways to get this working (asynchronous delegates, etc), but they consume a thread for each async operation, which doesn’t scale.
You are correct that
Async/Completedwill block an asynchronous page. (side note: I believe that they will not block a synchronous page – but I’ve never tried that – so if you’re using a non-async page, then you could try that). The method by which they “block” the asynchronous page is wrapped up inSynchronizationContext; in particular, each asynchronous page has a pending operation count which is incremented byAsyncand decremented afterCompleted.You should be able to fake out this count (note: I haven’t tried this either 😉 ). Just substitute the default
SynchronizationContext, which ignores the count:I wrote a class that handles the temporary replacement of
SynchronizationContext.Currentas part of the Nito.Async library. Using that class simplifies the code to:This solution does not consume a thread that just waits for the operation to complete. It just registers a callback and keeps the connection open until the response arrives.