1、創建線程的一種簡單方法是定義一個委托,並異步調用它。
1 using System; 2 using System.Threading; 3 4 delegate int WaitAWhileDelegate(int data, int ms); 5 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 WaitAWhileDelegate d = WaitAWhile; 11 int data = 1; 12 int ms = 3000; 13 IAsyncResult a = d.BeginInvoke(data, ms, null, null); 14 while (!a.IsCompleted) 15 { 16 Console.Write("*"); 17 Thread.Sleep(100); 18 } 19 int result = d.EndInvoke(a); 20 Console.WriteLine("\nresult: {0}", result); 21 } 22 23 static int WaitAWhile(int data, int ms) 24 { 25 Console.WriteLine("WaitAWhile started."); 26 Thread.Sleep(ms); 27 Console.WriteLine("WaitAWhile completed."); 28 return ++data; 29 } 30 }
增加代碼中第17行的Sleep方法的參數值,輸出的星號的個數會減少,反之會增加。
運行結果:
2、IAsyncResult有一個名字叫AsyncWaitHandle的屬性,該屬性的類型是WaitHandle類。該類的WaitOne方法會“將一個超時時間作為可選的第一個參數,在其中可以定義要等待的最長時間”。
1 using System; 2 using System.Threading; 3 4 class Program 5 { 6 delegate int WaitAWhileDelegate(int data, int ms); 7 8 static void Main(string[] args) 9 { 10 WaitAWhileDelegate d = new WaitAWhileDelegate(WaitAWhile); 11 int data = 1; 12 int ms = 3000; 13 IAsyncResult a = d.BeginInvoke(data, ms, null, null); 14 while (true) 15 { 16 Console.Write("*"); 17 if (a.AsyncWaitHandle.WaitOne(50, false)) 18 { 19 Console.WriteLine("Can get the result now."); 20 break; 21 } 22 } 23 int result = d.EndInvoke(a); 24 Console.WriteLine("\nresult: {0}", result); 25 } 26 27 static int WaitAWhile(int data, int ms) 28 { 29 Console.WriteLine("WaitAWhile started."); 30 Thread.Sleep(ms); 31 Console.WriteLine("WaitAWhile completed."); 32 return ++data; 33 } 34 }
運行結果:
3、等待結果的第三種方式是異步回調。IAsyncResult還有一個名字叫AsyncState的屬性。該屬性可以強制類型轉換為它的委托。
1 using System; 2 using System.Threading; 3 4 class Program 5 { 6 delegate int WaitAWhileDelegate(int data, int ms); 7 8 static void Main(string[] args) 9 { 10 WaitAWhileDelegate d = new WaitAWhileDelegate(WaitAWhile); 11 d.BeginInvoke(1, 1000, WaitAWhileComplete, d); 12 for (int i = 0; i < 100; i++) 13 { 14 Console.Write("*"); 15 Thread.Sleep(50); 16 } 17 } 18 19 static int WaitAWhile(int data, int ms) 20 { 21 Console.WriteLine("WaitAWhile started."); 22 Thread.Sleep(ms); 23 Console.WriteLine("WaitAWhile completed."); 24 return ++data; 25 } 26 27 static void WaitAWhileComplete(IAsyncResult a) 28 { 29 if (a == null) 30 { 31 throw new ArgumentNullException("a"); 32 } 33 WaitAWhileDelegate d = a.AsyncState as WaitAWhileDelegate; 34 if (d == null) 35 { 36 throw new Exception("a.AsyncState can not convert to WaitAWhileDelegate"); 37 } 38 int result = d.EndInvoke(a); 39 Console.WriteLine("\nresult: {0}", result); 40 } 41 }
注意,第11行代碼BeginInvoke方法中的第4個參數d不可以再為null,否則無法實現回調,即無法執行WaitAWhileComplete函數中第39行的打印輸出功能。
運行結果:
4、可以使用Lamda表達式代替委托。
1 using System; 2 using System.Threading; 3 4 class Program 5 { 6 delegate int WaitAWhileDelegate(int data, int ms); 7 8 static void Main(string[] args) 9 { 10 WaitAWhileDelegate d = new WaitAWhileDelegate(WaitAWhile); 11 d.BeginInvoke(1, 1000, a => { int result = d.EndInvoke(a); Console.WriteLine("\nresult: {0}", result); }, d); 12 for (int i = 0; i < 100; i++) 13 { 14 Console.Write("*"); 15 Thread.Sleep(50); 16 } 17 } 18 19 static int WaitAWhile(int data, int ms) 20 { 21 Console.WriteLine("WaitAWhile started."); 22 Thread.Sleep(ms); 23 Console.WriteLine("WaitAWhile completed."); 24 return ++data; 25 } 26 }
運行結果: