首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 网络安全-> 安全在线
在C#中使用代理的方式触发事件-.NET教程,C#语言
作者:网友供稿 点击:881
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
事件(event)是一个非常重要的概念,我们的程序时刻都在触发和接收着各种事件:鼠标点击事件,键盘事件,以及处理操作系统的各种事件。所谓事件就是由某个对象发出的消息。比如用户按下了某个按钮,某个文件发生了改变,socket上有数据到达。触发事件的对象称作发送者(sender),捕获事件并且做出响应的对象称作接收者(receiver),一个事件可以存在多个接受者。

在异步机制中,事件是线程之间进行通信的一个非常常用的方式。比如:用户在界面上按下一个按钮,执行某项耗时的任务。程序此时启动一个线程来处理这个任务,用户界面上显示一个进度条指示用户任务执行的状态。这个功能就可以使用事件来进行处理。可以将处理任务的类作为消息的发送者,任务开始时,发出“taskstart”事件,任务进行中的不同时刻发出“taskdoing”事件,并且携带参数说明任务进行的比例,任务结束的时候发出“taskdone”事件,在画面中接收并且处理这些事件。这样实现了功能,并且界面和后台执行任务的模块耦合程度也是最低的。

具体说c#语言,事件的实现依赖于“代理”(delegate)的概念,先了解一下代理。

代理(delegate)

delegate是c#中的一种类型,它实际上是一个能够持有对某个方法的引用的类。与其它的类不同,delegate类能够拥有一个签名(signature),并且它只能持有与它的签名相匹配的方法的引用。它所实现的功能与c/c++中的函数指针十分相似。它允许你传递一个类a的方法m给另一个类b的对象,使得类b的对象能够调用这个方法m。但与函数指针相比,delegate有许多函数指针不具备的优点。首先,函数指针只能指向静态函数,而delegate既可以引用静态函数,又可以引用非静态成员函数。在引用非静态成员函数时,delegate不但保存了对此函数入口指针的引用,而且还保存了调用此函数的类实例的引用。其次,与函数指针相比,delegate是面向对象、类型安全、可靠的受控(managed)对象。也就是说,runtime能够保证delegate指向一个有效的方法,你无须担心delegate会指向无效地址或者越界地址。

实现一个delegate是很简单的,通过以下3个步骤即可实现一个delegate:

1. 声明一个delegate对象,它应当与你想要传递的方法具有相同的参数和返回值类型。

2. 创建delegate对象,并将你想要传递的函数作为参数传入。

3. 在要实现异步调用的地方,通过上一步创建的对象来调用方法。

下面是一个简单的例子:

public class mydelegatetest

{

// 步骤1,声明delegate对象

public delegate void mydelegate(string name);

// 这是我们欲传递的方法,它与mydelegate具有相同的参数和返回值类型

public static void mydelegatefunc(string name)

{

console.writeline("hello, {0}", name);

}

public static void main ()

{

// 步骤2,创建delegate对象

mydelegate md = new mydelegate(mydelegatetest.mydelegatefunc);

// 步骤3,调用delegate

md("sam1111");

}

}



输出结果是:hello, sam1111

下面我们来看看事件是如何处理的:

事件(event)

c#中的事件处理实际上是一种具有特殊签名的delegate,象下面这个样子:

public delegate void myeventhandler(object sender, myeventargs e);

其中的两个参数,sender代表事件发送者,e是事件参数类。myeventargs类用来包含与事件相关的数据,所有的事件参数类都必须从system.eventargs类派生。当然,如果你的事件不含特别的参数,那么可以直接用system.eventargs类作为参数。

结合delegate的实现,我们可以将自定义事件的实现归结为以下几步:

1:定义delegate对象类型,它有两个参数,第一个参数是事件发送者对象,第二个参数是事件参数类对象。

2:定义事件参数类,此类应当从system.eventargs类派生。如果事件不带参数,这一步可以省略。

3:定义事件处理方法,它应当与delegate对象具有相同的参数和返回值类型。

4:用event关键字定义事件对象,它同时也是一个delegate对象。

5:用+=操作符添加事件到事件队列中(-=操作符能够将事件从队列中删除)。

6:在需要触发事件的地方用调用delegate的方式写事件触发方法。一般来说,此方法应为protected访问限制,既不能以public方式调用,但可以被子类继承。名字是可以是oneventname。

7:在适当的地方调用事件触发方法触发事件。

下面是一个例子,例子模仿容器和控件的模式,由控件触发一个事件,在容器中捕捉并且进行处理。

事件的触发者:

/// <summary>

/// 事件的触发者

/// </summary>

public class control

{

public delegate void somehandler(object sender, system.eventargs e);

 

/**

* 可以采用系统提供的system.eventhandler, 这里为了说明情况使用了自己定义的delegate

* 如果需要在事件的参数中使用自己定义的类型,也要自己定义delegate

*/

//public event system.eventhandler someevent;

public event somehandler someevent;

 

public control()

{

//这里使用的delegate必须与事件中声名的一致

//this.someevent += new system.eventhandler(this.control_someevent);

this.someevent += new somehandler(this.processsomeevent);

}

 

public void raisesomeevent()

{

eventargs e = new eventargs();

console.write("please input a:");

string s = console.readline();

 

//在用户输入一个小a的情况下触发事件,否则不触发

if (s == "a")

{

someevent(this, e);

}

}

 

//事件的触发者自己对事件进行处理,这个方法的参数必须和代理中声名的一致

private void processsomeevent(object sender, eventargs e)

{

console.writeline("hello");

}

}



事件的接收者:

/// <summary>

/// 事件的接收和处理者

/// </summary>

class container

{

private control ctrl = new control();

 

public container()

{

//这里使用的delegate必须与事件中声名的一致

//ctrl.someevent += new eventhandler(this.onsomeevent);

ctrl.someevent += new control.somehandler(this.responsesomeevent);

ctrl.raisesomeevent();

}

 

public static void main()

{

container pane = new container();

 

//这个readline是暂停程序用的,否则画面会一闪而过什么也看不见

console.readline();

}

 

//这是事件的接受者对事件的响应

private void responsesomeevent(object sender, eventargs e)

{

console.writeline("some event occur!");

}

}



程序运行的结果如下:

please input a:a

hello

some event occur!

 

事件的应用

例如有下面的需求需要实现:程序主画面中弹出一个子窗口。此时主画面仍然可以接收用户的操作(子窗口是非模态的)。子窗口上进行某些操作,根据操作的结果要在主画面上显示不同的数据。我发现一些程序员这样实现这个功能:

主画面弹出子窗口后,将自己的指针交给子画面,然后在子画面中使用这个指针,调用主画面提供的方法,改变主画面上的数据显示。这样虽然可以达到目的,但是各个模块之间产生了很强的耦合。一般说来模块之间的调用应该是单方向的:模块a调用了模块b,模块b就不应该反向调用a,否则就破坏了程序的层次,加强了耦合程度,也使得功能的改变和追加变得很困难。

这时正确的做法应该是在子窗口的操作过程中发出各种事件,而由主窗口捕捉这些事件进行处理,各个模块专心的做自己的事情,不需要过问其他模块的事情。


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·在C#中使用代理的方式触发事件-.NET教程,C#语言
·Java socket编程入门[1]-JSP教程,Java技巧及代码
·VB.NET 操作 ACCESS OLE 字段内容-.NET教程,VB.Net语言
·实例学习Spring和Hibernate的一点点体会-JSP教程,资料/其它
·《XML指南》下载[CHM格式-.NET教程,XML应用
·锂离子动力电池待解决的使用技术问题
·ASP.NET下的Page Controller以及Template Method-.NET教程,Asp.Net开发
·用C#实现WEB浏览器-.NET教程,C#语言
·在Visual Studio 2005和ASP.NET 2.0中使用强类型数据存取-.NET教程,Asp.Net开发
·ASP和C#隐藏文件下载路径的方法-ASP教程,ASP技巧
最新文章
·论arp攻击防制的基本方法_安全在线教程
·七种最不安全的网络管理员_安全在线教程
·windows网络安全其实我们只差五步_安全在线教程
·确保无线网络安全实施的几种技术规范_安全在线教程
·从两大方面阻止域名劫持_安全在线教程
·对网站做一些简单的seo处理_seo网站优化
·如何减轻ddos攻击危害_安全在线教程
·防火墙封阻应用攻击的八项技术_安全在线教程
·防火墙的来历及应用现状_安全在线教程
·浅析ids与ips共生与发展_安全在线教程
相关主题
  • 在c#中使用热键隐含窗口_c#应用
  • 在c#中使用可空类型_c#应用
  • 在C#中使用ADO.Net部件来访问Access数据库-.NET教程,数据库应用
  • 在C#中使用XML指南之读取XML-.NET教程,C#语言
  • 在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(二)----使用方法-.NET教程,C#语言
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭