The third option is the simplest one; it just uses an asynchronous delegate to start the task before sending the
response to the client. When the client browser renders the page after the
postback, the task is still running into another thread on the server and the
original thread, that initially served the request, is now free and returned in
the thread pool. You could look at the ThreadID into
the SimpleWorker's log file and compare the server
time when logging entries were added.
Listing 2 - Using asyncronous delegates
TraceStatusInfo("TEST CASE #3: Start a long running task asynchronously using an
asynchronous delegate.");
SimpleWorker w=new SimpleWorker();
atd2 = new AsyncTaskDelegate(w.DoWork);
TraceStatusInfo("Starting task");
atd2.BeginInvoke(int.Parse(txtUnits.Text), null, null);
litStatus.Text = "Test #3 completed.";
The difference between the two last approaches is on the
fact that the former can get the task result as it completes and informs the
user, the latter must poll the server to see what had happened, this should not
be an issue for some scenarios. However, an Ajax script could periodically hit
the server querying an activity registry, like a
table or a file, until the task is successfully completed. The second option
could also benefit from the timeout handler; the third option instead is best
suited for fire and forgets tasks.
Here is a snapshot of the log file in which you can see that
TreadID changes when an async task is executed in
tests cases #2 and #3.
Figure 2 - SimpleWorker's log file