When you do calls to components, which may need some time to respond, it is very essentially to put this calls in a separate thread. Otherwise you risk your application to bug for a while.
When you work with many threads sometimes you will need to pass data between them. Although .NET Framework provides an easy way to achieve this goal, I will show you another solution of this problem, which is more secure.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
class Program { static void Main() { ThreadStart myThreadDelegate = new ThreadStart(Program.MyHardWork); Console.WriteLine("I begin working..."); Thread myThread = new Thread(myThreadDelegate); myThread.Start(); } public static void MyHardWork() { Console.WriteLine("This method does so much work..."); } } |
Don’t forget to include using System.Threading; at the beginning. Well, everything is O.K. But now if you want to pass a parameter to this function? There is one standard way to do this, but I am going to show you another, a better one. When you create a new Thread object you may specify two delegates: ThreadStart or ParameterizedThreadStart. As you suppose, using the second delegate can help us.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
class Program { static void Main() { ParameterizedThreadStart myThreadDelegate = new ParameterizedThreadStart(Program.MyHardWork); Console.WriteLine("I begin working..."); Thread myThread = new Thread(myThreadDelegate); myThread.Start("boring"); } public static void MyHardWork(object what) { Console.WriteLine("This method does {0} work", what); } } |
Using ParameterizedThreadStart you can specify a void function, which accepts only one argument of type object. Then when you start the thread, you pass an object parameter. This technique is not very safe, because you can pass any object to the thread. A far better way is to create an auxiliary class, which includes a both the thread procedure and the data fields.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
class Program { static void Main() { Helper helper = new Helper("a great"); ThreadStart myThreadDelegate = new ThreadStart(helper.ThreadProc); Console.WriteLine("I begin working..."); Thread myThread = new Thread(myThreadDelegate); myThread.Start(); } } class Helper { private string what; public Helper(string what) { this.what = what; } public void ThreadProc() { Console.WriteLine("This method does {0} work...", this.what); } } |
This variant is safer and more convenient. Now, is you want your thread to do some work and then to return the results of its work, you can use a callback function. Here is simple example that illustrates this issue.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
public delegate void MyDelegate(string result); class Program { static void Main() { Helper helper = new Helper("a great", new MyDelegate(Program.FinalResult)); ThreadStart myThreadDelegate = new ThreadStart(helper.ThreadProc); Console.WriteLine("I begin working..."); Thread myThread = new Thread(myThreadDelegate); myThread.Start(); } public static void FinalResult(string result) { Console.WriteLine("My method ended with the words: {0}", result); } } class Helper { private string what; private MyDelegate myCallbackDelegate; public Helper(string what, MyDelegate myDelegate) { this.what = what; this.myCallbackDelegate = myDelegate; } public void ThreadProc() { Console.WriteLine("This method does {0} work...", this.what); if (myCallbackDelegate != null) myCallbackDelegate("I am complete!"); } } |
Well, that the whole technique! Its easy to use and modify.