Task任務、多線程、異步調用返回值問題


  在我們運用多線程,或者多任務作業時,有時候不可避免的會要的到某方法的運行結果,在這里總結任務、多線程和異步調用返回值問題。

  先創建一個Task<TResult>對象,與Task的區別在於Task<TResult>對象有個TResult類型的返回值。創建完對象調用Start()方法,為了獲取方法的返回值,要查詢Task<TResult>對象的Result屬性,如果任務還沒有完成他的工作,結果則不可用,Result屬性就會阻塞調用者。代碼如下

View Code
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()方法得到委托方法的返回值。代碼如下

View Code
 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組件來管理線程,在任務完成時引發事件,然后用事件處理程序處理結果。

View Code
 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).aspxhttp://msdn.microsoft.com/zh-cn/library/wkays279(v=vs.100).aspx

  自此推薦一篇學習多線程和異步調用的文章http://www.cnblogs.com/panjun-Donet/articles/1133627.html

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM