一个编译器所支持的异步委托的例子

类别:VC语言 点击:0 评论:0 推荐:

刚写的例子所以发发。。

http://www.lostinet.com/temp/asyncExample.txt

得到代码。

http://www.lostinet.com/temp/asyncExample.exe

运行程序

using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Threading; namespace AsyncExample { /// <summary> /// Form1 的摘要说明。 /// </summary> public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.TextBox textBox2; private System.Windows.Forms.Label label1; private System.Windows.Forms.Label label2; private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2; private System.ComponentModel.IContainer components; private System.Windows.Forms.Button button3; private Thread theThread; public Form1() { // // Windows 窗体设计器支持所必需的 // InitializeComponent(); // // TODO: 在 InitializeComponent 调用后添加任何构造函数代码 // //把当前线程记录起来,以后比较一下就知道一个函数是否在其他线程中执行了。 theThread=Thread.CurrentThread; } /// <summary> /// 清理所有正在使用的资源。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.groupBox1 = new System.Windows.Forms.GroupBox(); this.textBox1 = new System.Windows.Forms.TextBox(); this.textBox2 = new System.Windows.Forms.TextBox(); this.label1 = new System.Windows.Forms.Label(); this.label2 = 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.groupBox1.SuspendLayout(); this.SuspendLayout(); // // groupBox1 // this.groupBox1.Controls.AddRange(new System.Windows.Forms.Control[] { this.button3, this.button2, this.label2, this.label1, this.textBox2, this.textBox1, this.button1}); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(360, 128); this.groupBox1.TabIndex = 0; this.groupBox1.TabStop = false; this.groupBox1.Text = "输入两个数字"; // // textBox1 // this.textBox1.Location = new System.Drawing.Point(56, 24); this.textBox1.Name = "textBox1"; this.textBox1.TabIndex = 0; this.textBox1.Text = "111"; // // textBox2 // this.textBox2.Location = new System.Drawing.Point(56, 56); this.textBox2.Name = "textBox2"; this.textBox2.TabIndex = 1; this.textBox2.Text = "345"; // // label1 // this.label1.Location = new System.Drawing.Point(8, 24); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(40, 23); this.label1.TabIndex = 2; this.label1.Text = "数字1"; // // label2 // this.label2.Location = new System.Drawing.Point(8, 56); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(40, 23); this.label2.TabIndex = 3; this.label2.Text = "数字2"; // // button1 // this.button1.Location = new System.Drawing.Point(192, 24); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(144, 23); this.button1.TabIndex = 1; this.button1.Text = "使用Callback"; this.button1.Click += new System.EventHandler(this.button1_Click); // // button2 // this.button2.Location = new System.Drawing.Point(192, 56); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(144, 23); this.button2.TabIndex = 4; this.button2.Text = "使用EndInvoke"; this.button2.Click += new System.EventHandler(this.button2_Click); // // button3 // this.button3.Location = new System.Drawing.Point(192, 88); this.button3.Name = "button3"; this.button3.Size = new System.Drawing.Size(144, 23); this.button3.TabIndex = 5; this.button3.Text = "检测EndInvoke"; this.button3.Click += new System.EventHandler(this.button3_Click); // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.ClientSize = new System.Drawing.Size(360, 133); this.Controls.AddRange(new System.Windows.Forms.Control[] { this.groupBox1}); this.Name = "Form1"; this.Text = "Form1"; this.groupBox1.ResumeLayout(false); this.ResumeLayout(false); } #endregion /// <summary> /// 应用程序的主入口点。 /// </summary> [STAThread] static void Main() { Application.Run(new Form1()); } private bool GetNumbers(out double x,out double y) { try { x=double.Parse(textBox1.Text); y=double.Parse(textBox2.Text); return true; } catch(Exception) { x=0; y=0; return false; } } private delegate double 除的委托(double x,double y); /// <summary> /// 这个方法是今次要异步执行的方法 /// 因为它是作为From1的一个方法,所以能访问Form1的属性 /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <returns>a/b</returns> private double 除(double a,double b) { //取得方法执行所在的线程 Thread thisThread=Thread.CurrentThread; //在这个例子中,永远不成立。方法总是在其他线程中执行 if(thisThread==this.theThread) throw(new Exception("if(thisThread==this.theThread)")); MessageBox.Show(DateTime.Now.ToLongTimeString()+"\n按确定计算"+a+"/"+b+"的结果"); //如果b为0,那么就会抛出异常 //后面会有处理异步调用的异常的说明 return a/b; } #region CallBack调用例子 /// <summary> /// 使用CallBack来处理异步调用 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, System.EventArgs e) { double a,b; if(!GetNumbers(out a,out b)) { MessageBox.Show("请输入正确的数字"); return; } //可以在这里重新"."一下,看看有没有BeginInvoke的方法显示在列表中? //定义是没有的,所以IDE没有显示出来。 //不过编译器帮我们弄了这个方法,所以能编译通过 IAsyncResult iar=new 除的委托(除).BeginInvoke(a,b,new AsyncCallback(当除完成调用),"使用CallBack"); //关于BeginInvoke //new 除的委托(除) 这句不用多说了。 //new 除的委托(除).BeginInvoke 是编译器自动生成的函数。 //(a,b,new AsyncCallback(当除完成调用),"hello:)") 中 //a,b 是和 除的委托 的定义是一致的 //然后后面要加 AsyncCallback callback,object AsyncContext //看MSDN上对BeginInvoke的签名介绍。。 } private void 当除完成调用(IAsyncResult iar) { //这个是对的。不过我找不到文档说明是不是始终是对的。 System.Runtime.Remoting.Messaging.AsyncResult ar=(System.Runtime.Remoting.Messaging.AsyncResult)iar; //得到刚才的 new 除的委托(除) 除的委托 d=(除的委托)ar.AsyncDelegate; double res; Thread thisThread=Thread.CurrentThread; string msg=thisThread==this.theThread?"\n这个线程和主线程是一致的":"\n这个线程和主线程是不同的"; try { //和刚才的BeginInvoke像对应 res=d.EndInvoke(iar); //EndInvoke只需要放个IAsyncResult来做结束调用标志就够了。 //因为 除的委托 的定义,只有 In 参数,所以没有其他参数 //看MSDN上对BeginInvoke的签名介绍。。 MessageBox.Show("好了,,在 “除完成调用()”这个方法中,已经得到结果:\n"+res+msg); } catch(Exception x) { MessageBox.Show("好了,,在 “除完成调用()” 这个方法中检测到异常:\n"+x.Message+msg); } } #endregion #region 使用EndInvoke /// <summary> /// 这个是用来存放IAsyncResult的容器 /// </summary> ArrayList al=new ArrayList(); /// <summary> /// 使用EndInvoke来处理异步调用 /// 执行完这个,按确定来处理新弹出来的MessageBox /// 然后按"检测EndInvoke"来看看结果。。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, System.EventArgs e) { double a,b; if(!GetNumbers(out a,out b)) { MessageBox.Show("请输入正确的数字"); return; } //这个和上面的调用的最大区别就在参数AsyncCallback为null IAsyncResult iar=new 除的委托(除).BeginInvoke(a,b,null,"不使用Callback,直接使用iar.IsCompleted"); al.Add(iar); } //测试看看有没有什么东东是已经完成的。。 private void button3_Click(object sender, System.EventArgs e) { string msgs="好了,,在 “button3_Click()检测EndInvoke”这个方法中:"; Thread thisThread=Thread.CurrentThread; string msg=thisThread==this.theThread?"\n这个线程和主线程是一致的":"\n这个线程和主线程是不同的"; msgs+=msg+"\n\n"; int countMax=al.Count; int count=0; ArrayList alDelete=new ArrayList(); foreach(IAsyncResult iar in al) { //如果没有完成,看看下一个 if(!iar.IsCompleted)continue; //好了。。这个iar代表的调用是完成了的。 count++; //暂时不能修改al,所以只好这样 alDelete.Add(iar); //和上面的用法一样。 System.Runtime.Remoting.Messaging.AsyncResult ar=(System.Runtime.Remoting.Messaging.AsyncResult)iar; 除的委托 d=(除的委托)ar.AsyncDelegate; double res; try { //同上 res=d.EndInvoke(iar); msgs+=((string)iar.AsyncState)+"\n已经得到结果:\n"+res+"\n\n"; } catch(Exception x) { msgs+=((string)iar.AsyncState)+"\n检测到异常:\n"+x.Message+"\n\n"; } } //从al中删除已经执行完毕的调用的IAsyncResult foreach(IAsyncResult iar in alDelete) { al.Remove(iar); } if(countMax>0&&count==0) msgs+="倒,,还没有几个完成的。。"; if(countMax==0) msgs="没有任何的调用啊。。"; MessageBox.Show(msgs); } #endregion } }

本文地址:http://com.8s8s.com/it/it2171.htm