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

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 软件教学-> 文件管理
Remoting的事件机制(带具体例子)-.NET教程,评论及其它
作者:网友供稿 点击:53
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
概念就不说了,具体参见msdn相关章节:
http://msdn.microsoft.com/library/chs/cpguide/html/cpconevents.asp

我们先来改造一下上次的程序,为上次的主线程方法添加事件,能不断的引发事件来汇报处理的进度:
public class myeventargs
{
    
private int _rate;
    
    
public int rate
    {
        
get
        {
            
return _rate;
        }
    }

    
public myeventargs(int rate)
    {
        
this._rate=rate;
    }
}

public class myobject
{
    
public delegate void myeventhandler(object sender,myeventargs e);
    
public event myeventhandler myevent;

    
public void alongtimemethod(int time)
    {
        console.writeline(
"主线程方法开始");
        
for(int i=0;i<100;i++)
        {
            system.threading.thread.sleep(time);
            onmyevent(
new myeventargs(i));
        }
        console.writeline(
"主线程方法结束");
    }

    
protected void onmyevent(myeventargs e)
    {
        
if (myevent!=null)
        {
            myevent(
this,e);
        }
    }
}

再来为事件添加处理程序:

class myclient
{
    [stathread]
    
static void main(string[] args)
    {
        datetime dt
=datetime.now;
        myobject obj
=new myobject();
        obj.myevent
+=new myobject.myeventhandler(obj_myevent);
        obj.alongtimemethod(
50);
        console.writeline(
"用了"+((timespan)(datetime.now-dt)).totalseconds+"");
        console.readline();
    }

    
public static void obj_myevent(object sender,myeventargs e)
    {
        console.writeline(
"主线程方法完成了"+e.rate+"%");
    } 
}

运行程序可以看到:

这个是本地的,远程对象的事件也这么简单吗?其实没有想象的简单,因为对象是在远程的,服务端的事件客户端怎么捕捉?应该说远程对象的事件可以分成客户端触发-》服务器应答,服务端触发-》客户端应答和客户端触发-》客户端应答,第一种就很简单了,后面2种都需要有一个中间件。下面我们来要为程对象同样来添加一个进度机制,首先来建立我们的远程对象:

[serializable]
    
public class myeventargs:eventargs
    {
        
private int _rate;
        
private string _ip;

        
public int rate
        {
            
get
            {
                
return _rate;
            }
        }

        
public string ip
        {
            
get
            {
                
return _ip;
            }
        }

        
public myeventargs(int rate,string ip)
        {
            
this._rate=rate;
            
this._ip=ip;
        }
    }

    
public class myobject:marshalbyrefobject
    {
        
public delegate void myeventhandler(object sender,myeventargs e);
        
public event myeventhandler myevent;

        
public int alongtimemethod(int a,int b,int time,string ip)
        {
            console.writeline(
"异步方法开始");
            
for(int i=0;i<10;i++)
            {
                system.threading.thread.sleep(time);
                onmyevent(
new myeventargs(i,ip));
            }
            console.writeline(
"异步方法结束");
            
return a+b;
        }

        
protected void onmyevent(myeventargs e)
        {
            
if (myevent!=null)
            {
                myevent(
this,e);
            }
        }
    }

为了调试方便,服务器端和客户端这次都用程序实现,下面是服务器端:
using system;
using system.collections;
using system.runtime.remoting;
using system.runtime.remoting.channels;
using system.runtime.remoting.channels.tcp;
using system.runtime.serialization.formatters;

namespace remoteserver
{
    
class myserver
    {
        [stathread]
        
static void main(string[] args)
        {
            remotingconfiguration.registerwellknownservicetype(
typeof(remoteobject.myobject),"remoteobject.myobject",wellknownobjectmode.singleton);
            binaryserverformattersinkprovider serverprovider 
= new binaryserverformattersinkprovider(); 
            binaryclientformattersinkprovider clientprovider 
= new binaryclientformattersinkprovider(); 
            serverprovider.typefilterlevel 
= typefilterlevel.full; 
            idictionary props 
= new hashtable(); 
            props[
"port"]=9999
            tcpchannel channel 
= new tcpchannel(props,clientprovider,serverprovider); 
            channelservices.registerchannel(channel); 
            console.readline();
        }
    }
}

客户端为了简单一点,我去除了前面做测试的本地事件:
using system;
using system.net;
using system.collections;
using system.text;
using system.runtime.remoting;
using system.runtime.remoting.channels;
using system.runtime.remoting.channels.tcp;
using system.runtime.serialization.formatters;

class myclient
{
    
private delegate int mydelegate(int a,int b,int time,string ip);
    
private static mydelegate md;

    [stathread]
    
static void main(string[] args)
    {
        datetime dt
=datetime.now;
        remotingconfiguration.registerwellknownclienttype(
typeof(remoteobject.myobject), "tcp://localhost:9999/remoteobject.myobject");
        binaryserverformattersinkprovider serverprovider 
= new binaryserverformattersinkprovider(); 
        binaryclientformattersinkprovider clientprovider 
= new binaryclientformattersinkprovider(); 
        serverprovider.typefilterlevel 
= typefilterlevel.full; 
        idictionary props
=new hashtable(); 
        props[
"port"]=0
        tcpchannel channel 
= new tcpchannel(props,clientprovider,serverprovider); 
        channelservices.registerchannel(channel); 
        remoteobject.myobject app
=new remoteobject.myobject();
        app.myevent
+=new remoteobject.myobject.myeventhandler(myevent);
        md
=new mydelegate(app.alongtimemethod);
        asynccallback ac
=new asynccallback(myclient.callback);
        iphostentry iphe
=dns.gethostbyname(dns.gethostname());
        iasyncresult iar
=md.begininvoke(1,2,300,iphe.addresslist[0].tostring(),ac,null);
        method();
        console.writeline(
"用了"+((timespan)(datetime.now-dt)).totalseconds+"");
        channelservices.unregisterchannel(channel);
        console.readline();
    }

    
public static void callback(iasyncresult iar)
    {
        
if(iar.iscompleted)
        {
            console.writeline(
"结果是"+md.endinvoke(iar));
        }
    }

    
public static void myevent(object sender,remoteobject.myeventargs e)
    {
        console.writeline(
"来自"+e.ip+"的异步方法完成了"+e.rate*10+"%");
    } 

    
public static void method()
    {
        console.writeline(
"主线程方法开始");
        system.threading.thread.sleep(
5000);
        console.writeline(
"主线程方法结束");
    }
}

代码看上去不错,可是debug启动后报错:
 
这就是我前面提到的问题,远程不可能有本地的程序集,也无法触发本地事件。解决办法就是加一个事件中间件,继承marshalbyrefobject:
public class eventclass:marshalbyrefobject
    {
        
public void myevent(object sender,myeventargs e)
        {
            console.writeline(
"来自"+e.ip+"的异步方法完成了"+e.rate*10+"%");
        } 
    }

然后来修改一下客户端:
把app.myevent+=new remoteobject.myobject.myeventhandler(myevent);修改为
remoteobject.eventclass ec=new remoteobject.eventclass();
        app.myevent
+=new remoteobject.myobject.myeventhandler(ec.myevent);
删除客户端的myevent静态方法。

运行一下程序:


前后两个窗口本别是服务端和客户端的,貌似达到了我们的要求,其实不然,程序有2个漏洞:
1、客户端关闭以后打开新的程序就出错,因为以前的委托链丢失,服务端程序企图触发事件出错。
2、同时打开几个客户端,客户端收到的是所有的进度信息,而不仅仅是自己的,广播性质的消息。

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

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·C#:ListBox的2个常用方法Add,Clear与Items的2个属性-.NET教程,C#语言
·java连接sqlserver实例-JSP教程,Java技巧及代码
·Hibernate下数据批量处理解决方案-JSP教程,数据库相关
·一种基于pwm的电压输出dac电路设计
·delegate 与 多线程-.NET教程,算法/线程
·java Logging API 使用-JSP教程,Java技巧及代码
·ORACLE中LOB字段的使用和维护-ASP教程,数据库相关
·ups功率因数越大越好吗
·.NET三层经典架构PetShop3.0分析连载一-.NET教程,.NET Framework
·ASP后门之终极伪装-ASP教程,ASP基础
最新文章
·windows vista系统隐藏的12个网络工具_windows vista
·网站赚钱应如何选择网站联盟?_网赚技巧
·建站一级攻略 从看完之后就开始_站长心得
·论坛建设9大定律和经验分享_站长心得
·dreamweaver制作复杂交换图像_dreamweaver教程
·让你google广告90%不是公益广告的方法_google推广
·ppc 广告与转换率息息相关_google推广
·中国个人网站——新经济中的非主流1_站长心得
·blog设计的7个趋势_站长心得
·2005岁末blog程序大评点_站长心得
相关主题
  • RemotingIIS承载方式-.NET教程,评论及其它
  • Remoting的承载方式是这样的-.NET教程,评论及其它
  • Remoting和Web服务的区别-.NET教程,Web Service开发
  • Remoting服务端和客户端程序该这样模式来写-.NET教程,评论及其它
  • Remoting事件机制续-.NET教程,评论及其它
  • 西部数码虚拟主机

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