欢迎访问:常州市武进区嘉泽中心小学网站 !今天是:
栏目列表
您现在的位置是:首页>>教师>>计算机技术>>程序设计>>杂项>>文章内容
一个编译器所支持的异步委托的例子
发布时间:2008-11-20   点击:   来源:本站原创   录入者:佚名
 
刚写的例子所以发发。。
http://{域名已经过期}/temp/asyncExample.txt
得到代码。
运行程序
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

	}

}


附件:
    关闭窗口
    打印文档
    账号登录
    保持登录 忘记密码?
    账号与武进教师培训平台同步