zoukankan      html  css  js  c++  java
  • 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

     

  • 相关阅读:
    导包路径
    django导入环境变量 Please specify Django project root directory
    替换django的user模型,mysql迁移表报错 django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependen cy user.0001_initial on database 'default'.
    解决Chrome调试(debugger)
    check the manual that corresponds to your MySQL server version for the right syntax to use near 'order) values ('徐小波','XuXiaoB','男','1',' at line 1")
    MySQL命令(其三)
    MySQL操作命令(其二)
    MySQL命令(其一)
    [POJ2559]Largest Rectangle in a Histogram (栈)
    [HDU4864]Task (贪心)
  • 原文地址:https://www.cnblogs.com/xiangzhong/p/2512059.html
Copyright © 2011-2022 走看看