ThreadPool - Asynchronous delegates
ThreadPool.QueueUserWorkItem
doesn’t provide an easy mechanism for getting return values back from a thread after it has finished executing. Asynchronous delegate invocations (asynchronous delegates for short) solve this, allowing any number of typed arguments to be passed in both directions. Furthermore, unhandled exceptions on asynchronous delegates are conveniently rethrown on the original thread (or more accurately, the thread that callsEndInvoke
), and so they don’t need explicit handling.
Here’s how you start a worker task via an asynchronous delegate:
- Instantiate a delegate targeting the method you want to run in parallel (typically one of the predefined
Func
delegates). - Call
BeginInvoke
on the delegate, saving itsIAsyncResult
return value.BeginInvoke
returns immediately to the caller. You can then perform other activities while the pooled thread is working. - When you need the results, call
EndInvoke
on the delegate, passing in the savedIAsyncResult
object.
In the following example, we use an asynchronous delegate invocation to execute concurrently with the main thread, a simple method that returns a string’s length:
static void Main() { Func<string, int> method = Work; IAsyncResult cookie = method.BeginInvoke ("test", null, null); // // ... here's where we can do other work in parallel... // int result = method.EndInvoke (cookie); Console.WriteLine ("String length is: " + result); } static int Work (string s) { return s.Length; }
EndInvoke
does three things. First, it waits for the asynchronous delegate to finish executing, if it hasn’t already. Second, it receives the return value (as well as any ref
or out
parameters). Third, it throws any unhandled worker exception back to the calling thread.
No comments:
Post a Comment