在我們運用多線程,或者多任務作業時,有時候不可避免的會要的到某方法的運行結果,在這里總結任務、多線程和異步調用返回值問題。
先創建一個Task<TResult>對象,與Task的區別在於Task<TResult>對象有個TResult類型的返回值。創建完對象調用Start()方法,為了獲取方法的返回值,要查詢Task<TResult>對象的Result屬性,如果任務還沒有完成他的工作,結果則不可用,Result屬性就會阻塞調用者。代碼如下

1 Task<int> task = new Task<int>(() => Test());//創建任務 2 Taskw.Start();//開始任務 3 int result = Taskw.Result;//得到調用方法的結果 4 5 public int Test() 6 { 7 //方法體 8 }
異步調用返回結果我們必須用到IAsyncResult對象。首先我們通過委托調用需要異步執行的方法,在結束異步時,調用方法EndInvoke()方法得到委托方法的返回值。代碼如下

1 private string[] MainTest() 2 { 3 weatherdelegate wd = new weatherdelegate(getResut); 4 IAsyncResult iresult = wd.BeginInvoke(null, null); 5 iresult.AsyncWaitHandle.WaitOne();//阻止當前線程,直到收到信號 6 string[] s = wd.EndInvoke(iresult); 7 iresult.AsyncWaitHandle.Close();//釋放所有資源 8 return s; 9 } 10 11 //異步執行的方法 12 public string[] Test() 13 { 14 // 15 }
在多線程應用程序中提供和返回值是很復雜的,因此必須對某個過程的引用傳遞給線程類的構造函數,該過程不帶參數也不返回值。
由於這些過程不能為函數也不能使用ByRef參數,因此從運行於不同線程的過程返回值是很復雜的。返回值的最簡單方法是:使用BackgroundWorker組件來管理線程,在任務完成時引發事件,然后用事件處理程序處理結果。

1 class AreaClass2 2 { 3 public double Base; 4 public double Height; 5 public double CalcArea() 6 { 7 // Calculate the area of a triangle. 8 return 0.5 * Base * Height; 9 } 10 } 11 12 private System.ComponentModel.BackgroundWorker BackgroundWorker1 13 = new System.ComponentModel.BackgroundWorker(); 14 15 private void TestArea2() 16 { 17 InitializeBackgroundWorker(); 18 19 AreaClass2 AreaObject2 = new AreaClass2(); 20 AreaObject2.Base = 30; 21 AreaObject2.Height = 40; 22 23 // Start the asynchronous operation. 24 BackgroundWorker1.RunWorkerAsync(AreaObject2); 25 } 26 27 private void InitializeBackgroundWorker() 28 { 29 // Attach event handlers to the BackgroundWorker object. 30 BackgroundWorker1.DoWork += 31 new System.ComponentModel.DoWorkEventHandler(BackgroundWorker1_DoWork); 32 BackgroundWorker1.RunWorkerCompleted += 33 new System.ComponentModel.RunWorkerCompletedEventHandler(BackgroundWorker1_RunWorkerCompleted); 34 } 35 36 private void BackgroundWorker1_DoWork( 37 object sender, 38 System.ComponentModel.DoWorkEventArgs e) 39 { 40 AreaClass2 AreaObject2 = (AreaClass2)e.Argument; 41 // Return the value through the Result property. 42 e.Result = AreaObject2.CalcArea(); 43 } 44 45 private void BackgroundWorker1_RunWorkerCompleted( 46 object sender, 47 System.ComponentModel.RunWorkerCompletedEventArgs e) 48 { 49 // Access the result through the Result property. 50 double Area = (double)e.Result; 51 MessageBox.Show("The area is: " + Area.ToString()); 52 }
更多關於多線程返回值參見http://technet.microsoft.com/zh-cn/magazine/wkays279(VS.90).aspx和http://msdn.microsoft.com/zh-cn/library/wkays279(v=vs.100).aspx
自此推薦一篇學習多線程和異步調用的文章http://www.cnblogs.com/panjun-Donet/articles/1133627.html