CSDN博客

img Lostinet

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

发表于2002/11/29 16:37:00  1131人阅读

刚写的例子所以发发。。
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
	}
}
阅读全文
0 0

相关文章推荐

img
取 消
img