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

 

原文地址:https://www.cnblogs.com/xiangzhong/p/2512059.html