ThreadStart
In general, one should create a new thread instance for long-running tasks ...
ThreadStart job = new ThreadStart(ThreadJob); Thread thread = new Thread(job); thread.Start(); static void ThreadJob() { // do something }
ThreadStart delegate doesn't take any parameters, so the state/information has to be stored somewhere else. WaitCallback can be used to create a new instance of a class and use it to store the state/information. Often the class itself can contain the delegate used for starting the thread.
class WorkerThreadState { private WaitCallback _callback; private object _data; public WorkerThreadState( WaitCallback callback, object data ) { if ( callback == null ) throw new ArgumentNullException( "callback" ); _callback = callback; _data = data; } // ThreadStart delegate public void Execute() { _callback( _data ); } // WaitCallback delegate static void MyMethod( object state ) { Console.WriteLine( "State: " + state ); } static void Main() { string state = "Hello, background world!"; WaitCallback wcb = new WaitCallback(MyMethod); WorkerThreadState wts = new WorkerThreadState(wcb, state); ThreadStart ts = new ThreadStart(wts.Execute); Thread t = new Thread(ts); t.Start(); } }
Some points to note here ...
- MyMethod can't be wrapped with a ThreadStart delegate given different signatures
- MyMethod is wrapped with a WaitCallback (correct signature)
- WaitCallback and the state to be supplied to it are wrapped in a new WorkerThreadState instance
- Since WorkerThreadState is parameterless, Execute method is wrapped with a ThreadStart delegate
In the example above, delegate (.Net 2+) can be used as follows ...
WorkerThreadState wts = new WorkerThreadState(MyMethod, state); Thread t = new Thread(wts.Execute); t.Start();
One can also access variables (including local variables and parameters of the "outside" method) within the anonymous method as follows ...
ThreadStart starter = delegate { Fetch (myUrl); }; Thread t = new Thread(starter); t.Start();
ParameterizedThreadStart [.Net 2.0]
Some points of interest here are ...
- ParameterizedThreadStart has the same signature as WaitCallback. It can thus be used with methods that accept a single object parameter
- One can create a thread using an instance of this delegate
- Thread.Start overload now allows the value to be passed to the new thread
- This is simple, but only accepts a single parameter and isn't type-safe (just like the options when using thread pool threads)
ParameterizedThreadStart pts = new ParameterizedThreadStart(FetchUrl); Thread t = new Thread (pts); t.Start (myUrl);
Or using delegates, this could be rewritten as:
Thread t = new Thread (FetchUrl);
t.Start (myUrl); ThreadPool
Thread pools should be used only for brief job
Synchronous:
ThreadPool.QueueUserWorkItem
Asynchronous: Allows multiple strongly typed parameters
Stream.BeginRead
delegate.BeginInvoke Anonymous methods [.Net 2.0]: One can access variables (including local variables and parameters of the "outside" method) within the anonymous method
WaitCallback callback = delegate (object state) { Fetch (string)state); }; ThreadPool.QueueUserWorkItem (callback, myUrl);
References
http://www.yoda.arachsys.com/csharp/threads/ http://msdn.microsoft.com/msdnmag/issues/06/06/NETMatters/default.aspx


0 comments:
Post a Comment