Reputation: 7525
When a user clicks a button, I use the ThreadPool.QueueUserWorkItem
to spawn a thread that kicks off a long running process. I would like to make a button visible when the thread is completed so that user can click on it.
Is there a completed event in ThreadPool
What am I trying to do?
One of the pages has a button when clicked connects to a WS and kicks off a long running process that creates a file. During the processing time, I would like to show a progress bar to the user. Once the processing is completed, I would like to provide a link to the file that was created. Many users will be clicking on the button the same time that creates different files. I guess you would call this a single request that can be implemented using the Async approach?
Quick Qs about Async pages:
The MSDN link has the following code:
AddOnPreRenderCompleteAsync ( new BeginEventHandler(MyBeginMethod), new EndEventHandler (MyEndMethod) );
It appears that the MyBeginMethod
is kicked off on Page Load, will the same code snippet work for me if i want to initiate the async process on a button click?
MyBeginMethod
and MyEndMethod
methods (so that I can make a download file button visible on the process completion? Or does a different thread own these controls?Upvotes: 2
Views: 1562
Reputation:
Nope.
You'll have to store the fact you've completed somewhere available to your ASP.NET pages and the method doing your work, like the HttpCache.
If this is all happening within a single request, skip the thread pool and check out asynchronous pages.
First, if the file is created per user, then the result of the long running action should be stored in the Session, not the cache. The cache is shared between users, and the session is per-user.
The long running task can create the file, then store the file path in the session for that user. Whenever the user sends another request for the file, the session is checked for this file.
There are a few options for the UI during this. One is by postbacks to the server, the other is ajax calls.
Ajax may not be the easiest, even though there are plenty of frameworks (like jQuery) and lots of information on the net about how to make an asynchronous postback. If the process is very long, users might browse away, etc, making your task harder to implement.
Another option is to make your request for the file, then redirect to a holding page. This holding page has a script that automatically refreshes every X seconds. It displays to the user a notification such as "Please wait, creating your file." Every time this page posts back to the server the existence of the file is checked. If its not ready yet, then you return to the holding page. Eventually, the file becomes ready and you can redirect the user to another page where the file is downloaded/displayed/whatever.
The second option is probably easier and more straightforward for you to implement. Here's the pseudocode:
Upvotes: 4
Reputation: 273581
No, there is no completed event in ThreadPool
, nor is there an easy way to Join()
.
That is one of the issues that the Task class solves in .NET4. Tasks have a Wait() method.
In the mean time, follow the recommendations from Will's answer. Asynchronous ASP.NET is easy to get wrong.
Upvotes: 1