Nick
Nick

Reputation: 7525

ThreadPool.QueueUserWorkItem completed event?

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:

  1. 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?

  1. Can I access the UI controls in 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

Answers (2)

user1228
user1228

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:

  1. User clicks a link to get the file
  2. On postback, server redirects to the holding page
  3. User's browser is redirected to the holding page
  4. Request is handled by the holding page. The Session is checked for the file.
    1. If the session reports the file has not been, and is not being created, the file creation process is started. The holding page is returned to the user.
    2. If the session reports the file is being created, the holding page is returned to the user.
    3. If the session reports the file is made, the user is redirected to the download page
  5. The holding page has a javascript method that runs on load that reloads the page every X seconds.

Upvotes: 4

Henk Holterman
Henk Holterman

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

Related Questions