浅谈.Net的异步

        在学习异步前有必要讨论“我们为什么要了解异步”,也就是异步对我们编写程序有什么好处。现说说同步把,所谓同步就是按照程序编码的顺序执行,异步说的粗糙点就是不按照编码的顺序执行,我们什么时候需要进行异步编程呢--------如果我们遇到某个任务特别费时,由于下面执行的任务和上个任务无关,我们可以用异步执行(当然也可以用多线程);知道什么时候使用异步,那我们接下来开始学习异步编程吧。
       一,异步编程的步骤
1,建立与被调用方法相同签名的委托

假设被调用的方法为public void TestMethod(string p)

Public delegate void  AsyncDelegate(string p);

2,把被调用的方法注册到委托实例

AsyncDelegate ad=new AsyncDelegate(TestMethod);

3,以begininvoke开始调用异步方法

IAsyncResult ar =Ad.BeginInvoke(string p,null,null)

4,继续做一些不需要异步调用结果的操作

//做一些其它操作

5,在需要异步调用方法结果的时候,察看异步调用方法执行的结果,并同步等待异步调用完成。

 while(ar.IsCompleted == false)

 {

            Thread.Sleep(10);

        }

Ad.EndBeginInvoke();

//继续操作

二, 实例
 

using System;

using System.Drawing;

using System.Collections;

using System.ComponentModel;

using System.Windows.Forms;

using System.Data;

 

 

namespace TestAsyn

{

   //声明与被调用方法相同的委托

   public delegate void AddHandle();

   /// <summary>

   /// Form1 的摘要说明。

   /// </summary>

   public class Form1 : System.Windows.Forms.Form

   {

      private System.Windows.Forms.Label label1;

      private System.Windows.Forms.Button button1;

      private System.Windows.Forms.Button button2;

      public AddHandle add;

      private System.Windows.Forms.Button button3;

      private System.Windows.Forms.Button button4;

      private IAsyncResult ar;

      private System.Windows.Forms.Label label2;

     

      /// <summary>

      /// 必需的设计器变量。

      /// </summary>

      private System.ComponentModel.Container components = null;

 

      public Form1()

      {

        //

        // Windows 窗体设计器支持所必需的

        //

        InitializeComponent();

 

        //

        // TODO: InitializeComponent 调用后添加任何构造函数代码

        //

      }

 

      /// <summary>

      /// 清理所有正在使用的资源。

      /// </summary>

      protected override void Dispose( bool disposing )

      {

        if( disposing )

        {

           if (components != null)

           {

              components.Dispose();

           }

        }

        base.Dispose( disposing );

      }

 

      #region Windows 窗体设计器生成的代码

      /// <summary>

      /// 设计器支持所需的方法 - 不要使用代码编辑器修改

      /// 此方法的内容。

      /// </summary>

      private void InitializeComponent()

      {

        this.label1 = new System.Windows.Forms.Label();

        this.button1 = new System.Windows.Forms.Button();

        this.button2 = new System.Windows.Forms.Button();

        this.button3 = new System.Windows.Forms.Button();

        this.button4 = new System.Windows.Forms.Button();

        this.label2 = new System.Windows.Forms.Label();

        this.SuspendLayout();

        //

        // label1

        //

        this.label1.Location = new System.Drawing.Point(152, 32);

        this.label1.Name = "label1";

        this.label1.Size = new System.Drawing.Size(152, 23);

        this.label1.TabIndex = 0;

        //

        // button1

        //

        this.button1.Location = new System.Drawing.Point(88, 88);

        this.button1.Name = "button1";

        this.button1.Size = new System.Drawing.Size(336, 23);

        this.button1.TabIndex = 1;

        this.button1.Text = "同步操作(程序会在未执行完失去相应)";

        this.button1.Click += new System.EventHandler(this.button1_Click);

        //

        // button2

        //

        this.button2.Location = new System.Drawing.Point(88, 144);

        this.button2.Name = "button2";

        this.button2.Size = new System.Drawing.Size(328, 23);

        this.button2.TabIndex = 2;

        this.button2.Text = "异步执行(但还是没用相应)";

        this.button2.Click += new System.EventHandler(this.button2_Click);

        //

        // button3

        //

        this.button3.Location = new System.Drawing.Point(8, 208);

        this.button3.Name = "button3";

        this.button3.Size = new System.Drawing.Size(312, 23);

        this.button3.TabIndex = 3;

        this.button3.Text = "异步执行(可以做一些不需要异步调用结果的操作)";

        this.button3.Click += new System.EventHandler(this.button3_Click);

        //

        // button4

        //

        this.button4.Location = new System.Drawing.Point(344, 208);

        this.button4.Name = "button4";

        this.button4.Size = new System.Drawing.Size(312, 23);

        this.button4.TabIndex = 4;

        this.button4.Text = "异步执行(需要做一些需要异步调用结果的操作)";

        this.button4.Click += new System.EventHandler(this.button4_Click);

        //

        // label2

        //

        this.label2.Location = new System.Drawing.Point(96, 272);

        this.label2.Name = "label2";

        this.label2.Size = new System.Drawing.Size(488, 23);

        this.label2.TabIndex = 5;

        this.label2.Text = "提示信息:";

        //

        // Form1

        //

        this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);

        this.ClientSize = new System.Drawing.Size(680, 413);

        this.Controls.Add(this.label2);

        this.Controls.Add(this.button4);

        this.Controls.Add(this.button3);

        this.Controls.Add(this.button2);

        this.Controls.Add(this.button1);

        this.Controls.Add(this.label1);

        this.Name = "Form1";

        this.Text = "Form1";

        this.Load += new System.EventHandler(this.Form1_Load);

        this.ResumeLayout(false);

 

      }

      #endregion

 

      /// <summary>

      /// 应用程序的主入口点。

      /// </summary>

      [STAThread]

      static void Main()

      {

        Application.Run(new Form1());

       

      }

      private void AddMethod()

      {

        for(int i=0;i<10000;i++)

        {

           this.label1.Text=i.ToString();

       

        }

      }

      private void button1_Click(object sender, System.EventArgs e)

      {

        this.AddMethod();

       

       }

 

      private void button2_Click(object sender, System.EventArgs e)

      {

        IAsyncResult ar=this.add.BeginInvoke(null,null);

         this.add.EndInvoke(ar);

 

      }

 

      private void Form1_Load(object sender, System.EventArgs e)

      {

        //把被调用的方法注册到委托上

        this.add=new AddHandle(this.AddMethod);

      }

 

      private void button3_Click(object sender, System.EventArgs e)

      {

         this.ar=this.add.BeginInvoke(null,null);

      }

 

      private void button4_Click(object sender, System.EventArgs e)

      {

     

        if(!this.ar.IsCompleted)

        {

 

           this.label2.Text="提示信息:异步方法还没有执行完,请等待。";

        }

        else

        {

           this.add.EndInvoke(this.ar);

           MessageBox.Show("异步操作完成,弹出一对话框");

        }

//      this.add.EndInvoke(this.ar);

//    MessageBox.Show("异步操作完成,弹出一对话框");

      }

   }

}

 

三,在异步调用中使用IAsyncResult(表示异步操作的状态)和AsyncCallback(异步调用完成时执行回调方法)
  1,建立与被调用方法相同签名的委托

假设被调用的方法为public void TestMethod(string p)

Public delegate void  AsyncDelegate(string p);

2,把被调用的方法注册到委托实例

AsyncDelegate ad=new AsyncDelegate(TestMethod);

3,定义异步调用完成时执行的回调方法

Public void CallbackMethod(IAsyncResult ar)

4,以begininvoke开始调用异步方法

IAsyncResult ar =Ad.BeginInvoke(string p,new AsyncCallback(CallbackMethod),null)

5,继续做一些不需要异步调用结果的操作

//做一些其它操作

四,实例
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;


namespace TestAsyn
{
 //声明与被调用方法相同的委托
 public delegate void AddHandle();
 /// <summary>
 /// Form1 的摘要说明。
 /// </summary>
 public class Form1 : System.Windows.Forms.Form
 {
  private System.Windows.Forms.Label label1;
  private System.Windows.Forms.Button button1;
  private System.Windows.Forms.Button button2;
  public AddHandle add;
  private System.Windows.Forms.Button button3;
  private System.Windows.Forms.Button button4;
  private IAsyncResult ar;
  private System.Windows.Forms.Label label2;
  private System.Windows.Forms.Button button5;
  
  /// <summary>
  /// 必需的设计器变量。
  /// </summary>
  private System.ComponentModel.Container components = null;
  public string Labeltext
  {
   get
   {
   return this.label1.Text;
   }
  }
  public Form1()
  {
   //
   // Windows 窗体设计器支持所必需的
   //
   InitializeComponent();

   //
   // TODO: 在 InitializeComponent 调用后添加任何构造函数代码
   //
  }

  /// <summary>
  /// 清理所有正在使用的资源。
  /// </summary>
  protected override void Dispose( bool disposing )
  {
   if( disposing )
   {
    if (components != null)
    {
     components.Dispose();
    }
   }
   base.Dispose( disposing );
  }

  #region Windows 窗体设计器生成的代码
  /// <summary>
  /// 设计器支持所需的方法 - 不要使用代码编辑器修改
  /// 此方法的内容。
  /// </summary>
  private void InitializeComponent()
  {
   this.label1 = new System.Windows.Forms.Label();
   this.button1 = new System.Windows.Forms.Button();
   this.button2 = new System.Windows.Forms.Button();
   this.button3 = new System.Windows.Forms.Button();
   this.button4 = new System.Windows.Forms.Button();
   this.label2 = new System.Windows.Forms.Label();
   this.button5 = new System.Windows.Forms.Button();
   this.SuspendLayout();
   //
   // label1
   //
   this.label1.Location = new System.Drawing.Point(152, 32);
   this.label1.Name = "label1";
   this.label1.Size = new System.Drawing.Size(152, 23);
   this.label1.TabIndex = 0;
   //
   // button1
   //
   this.button1.Location = new System.Drawing.Point(88, 88);
   this.button1.Name = "button1";
   this.button1.Size = new System.Drawing.Size(336, 23);
   this.button1.TabIndex = 1;
   this.button1.Text = "同步操作(程序会在未执行完失去相应)";
   this.button1.Click += new System.EventHandler(this.button1_Click);
   //
   // button2
   //
   this.button2.Location = new System.Drawing.Point(88, 144);
   this.button2.Name = "button2";
   this.button2.Size = new System.Drawing.Size(328, 23);
   this.button2.TabIndex = 2;
   this.button2.Text = "异步执行(但还是没用相应)";
   this.button2.Click += new System.EventHandler(this.button2_Click);
   //
   // button3
   //
   this.button3.Location = new System.Drawing.Point(8, 208);
   this.button3.Name = "button3";
   this.button3.Size = new System.Drawing.Size(312, 23);
   this.button3.TabIndex = 3;
   this.button3.Text = "异步执行(可以做一些不需要异步调用结果的操作)";
   this.button3.Click += new System.EventHandler(this.button3_Click);
   //
   // button4
   //
   this.button4.Location = new System.Drawing.Point(344, 208);
   this.button4.Name = "button4";
   this.button4.Size = new System.Drawing.Size(312, 23);
   this.button4.TabIndex = 4;
   this.button4.Text = "异步执行(需要做一些需要异步调用结果的操作)";
   this.button4.Click += new System.EventHandler(this.button4_Click);
   //
   // label2
   //
   this.label2.Location = new System.Drawing.Point(96, 272);
   this.label2.Name = "label2";
   this.label2.Size = new System.Drawing.Size(488, 23);
   this.label2.TabIndex = 5;
   this.label2.Text = "提示信息:";
   //
   // button5
   //
   this.button5.Location = new System.Drawing.Point(136, 328);
   this.button5.Name = "button5";
   this.button5.Size = new System.Drawing.Size(304, 23);
   this.button5.TabIndex = 6;
   this.button5.Text = "异步执行(执行完成自动调用回调方法)";
   this.button5.Click += new System.EventHandler(this.button5_Click);
   //
   // Form1
   //
   this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
   this.ClientSize = new System.Drawing.Size(680, 413);
   this.Controls.Add(this.button5);
   this.Controls.Add(this.label2);
   this.Controls.Add(this.button4);
   this.Controls.Add(this.button3);
   this.Controls.Add(this.button2);
   this.Controls.Add(this.button1);
   this.Controls.Add(this.label1);
   this.Name = "Form1";
   this.Text = "Form1";
   this.Load += new System.EventHandler(this.Form1_Load);
   this.ResumeLayout(false);

  }
  #endregion

  /// <summary>
  /// 应用程序的主入口点。
  /// </summary>
  [STAThread]
  static void Main()
  {
   Application.Run(new Form1());
   
  }
  private void  AddMethod()
  {
   for(int i=0;i<10000;i++)
   {
    this.label1.Text=i.ToString();
   
   }
  }
  private void button1_Click(object sender, System.EventArgs e)
  {
   this.AddMethod();
   
  }

  private void button2_Click(object sender, System.EventArgs e)
  {
   IAsyncResult ar=this.add.BeginInvoke(null,null);
   this.add.EndInvoke(ar);

  }

  private void Form1_Load(object sender, System.EventArgs e)
  {
   //把被调用的方法注册到委托上
   this.add=new AddHandle(this.AddMethod);
  }

  private void button3_Click(object sender, System.EventArgs e)
  {
   this.ar=this.add.BeginInvoke(null,null);
  }
  public void CallBackMethod(IAsyncResult ar)
  {
  Form1 f = (Form1) ar.AsyncState;
  MessageBox.Show("执行完成,窗体上label1的text的值为"+f.Labeltext);
  }
  private void button4_Click(object sender, System.EventArgs e)
  {
  
   if(!this.ar.IsCompleted)
   {

    this.label2.Text="提示信息:异步方法还没有执行完,请等待。";
   }
   else
   {
    this.add.EndInvoke(this.ar);
    MessageBox.Show("异步操作完成,弹出一对话框");
   }
   //   this.add.EndInvoke(this.ar);
   //  MessageBox.Show("异步操作完成,弹出一对话框");
  }

  private void button5_Click(object sender, System.EventArgs e)
  {
   this.ar=this.add.BeginInvoke(new AsyncCallback(this.CallBackMethod),this);
  }
 }
}
五,总结“异步方法签名”
方法签名是参数类型在一个方法中的顺序。BeginInvoke 异步方法签名的规则是:

  • 包括所有 IN 参数。
  • 包括所有 OUT 参数。
  • 包括所有 IN/OUT 参数。
  • 包括所有 ByRef 参数。
  • AsyncCallback AsyncState(可通过 IAsyncResult 接口的 AsyncState 属性获得)作为最后两个参数。
  • 返回 IAsyncResult

EndInvoke 异步方法签名的规则是:

  • 包括所有 IN/OUT 参数。
  • 包括所有 OUT 参数。
  • 包括所有 ByRef 参数。
  • IAsyncResult 作为最后一个参数。
  • 从原始方法签名返回原始返回类型。

结果对象 (IAsyncResult) 是从开始操作返回的,并且可用于获取有关异步开始操作是否已完成的状态。结果对象被传递到结束操作,该操作返回调用的最终返回值。在开始操作中可以提供可选的回调。如果提供回调,在调用结束后,将调用该回调;并且回调中的代码可以调用结束操作。


 

posted on 2006-12-06 20:34  网络小贩  阅读(572)  评论(0编辑  收藏  举报

导航