Remoting Event 远程事件
来源:互联网 发布:网络鲨鱼 编辑:程序博客网 时间:2024/05/13 20:14
在.Net Remoting的应用中,经常碰到需要预定Remoting Object的事件的情况,要能使远程事件发布/预定如预期中的进行,需要注意如下问题:
1. Remoting 配置
在Remoting配置文件中,需要将typeFilterLevel设置为Full,否则,将出现RemotingHandler无法序列化的异常。
如可能的channels配置:
《Server端》
《对应的Client端》
2.客户端中预定事件的宿主类(以下称 host class)必须从MarshalByRefObject继承。这是因为当host class将事件处理句柄注册到远程服务器时,句柄中包含了host class的引用,所以host class需要从MarshalByRefObject继承,以便远程服务对象能取得host class引用。这个时候,可以将host class看成远程服务对象,而真正的RemotingObject变成了客户端。
3.事件处理函数必须是public的,因为真正的RemotingObject需要通过host class的代理访问到这个函数,如果是private,将会抛出“无法序列化private方法”的异常。
4.远程服务端需要引用(在运行时自动查找)host class所在的Assembly,所以如果host class仅包含在客户应用程序(如Client.exe)中,则需要将Client.exe拷贝到远程服务器程序所在目录。最好的办法是,将host class放在一个公共的.dll中,然后分别由服务器和客户端引用。
5.事件处理函数若含有引用类型的参数,则参数要么是可序列化的,要么从MarshalByRefObject继承,原因同三。当参数类型是从MarshalByRefObject继承的时候,就更复杂了,需要你仔细分析(因为这个参数类型中可能还包含其它的引用类型)。
6.事件处理函数抛出的异常必须是可序列化的--其实,你应该保证所有的自定义异常都必须是可序列化的。
7.Remoting Object在触发远程事件的时候,必须对每一个事件处理函数进行论询触发,并捕获每一次触发抛出的异常,否则,当异常发生后,后面的事件处理函数就不会被调用了。应该像下面这样:
如果你遇到过的问题,这里没有列出来,请留言和我讨论:)
1. Remoting 配置
在Remoting配置文件中,需要将typeFilterLevel设置为Full,否则,将出现RemotingHandler无法序列化的异常。
如可能的channels配置:
《Server端》
<channels>
<channel ref="tcp" port="9009" >
<serverProviders>
<provider ref="wsdl" />
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
<clientProviders>
<formatter ref="binary" />
</clientProviders>
</channel>
</channels>
<channel ref="tcp" port="9009" >
<serverProviders>
<provider ref="wsdl" />
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
<clientProviders>
<formatter ref="binary" />
</clientProviders>
</channel>
</channels>
《对应的Client端》
<channels>
<channel ref="tcp" port="0">
<serverProviders>
<provider ref="wsdl" />
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
<channel ref="tcp" port="0">
<serverProviders>
<provider ref="wsdl" />
<formatter ref="soap" typeFilterLevel="Full" />
<formatter ref="binary" typeFilterLevel="Full" />
</serverProviders>
</channel>
</channels>
2.客户端中预定事件的宿主类(以下称 host class)必须从MarshalByRefObject继承。这是因为当host class将事件处理句柄注册到远程服务器时,句柄中包含了host class的引用,所以host class需要从MarshalByRefObject继承,以便远程服务对象能取得host class引用。这个时候,可以将host class看成远程服务对象,而真正的RemotingObject变成了客户端。
3.事件处理函数必须是public的,因为真正的RemotingObject需要通过host class的代理访问到这个函数,如果是private,将会抛出“无法序列化private方法”的异常。
4.远程服务端需要引用(在运行时自动查找)host class所在的Assembly,所以如果host class仅包含在客户应用程序(如Client.exe)中,则需要将Client.exe拷贝到远程服务器程序所在目录。最好的办法是,将host class放在一个公共的.dll中,然后分别由服务器和客户端引用。
5.事件处理函数若含有引用类型的参数,则参数要么是可序列化的,要么从MarshalByRefObject继承,原因同三。当参数类型是从MarshalByRefObject继承的时候,就更复杂了,需要你仔细分析(因为这个参数类型中可能还包含其它的引用类型)。
6.事件处理函数抛出的异常必须是可序列化的--其实,你应该保证所有的自定义异常都必须是可序列化的。
7.Remoting Object在触发远程事件的时候,必须对每一个事件处理函数进行论询触发,并捕获每一次触发抛出的异常,否则,当异常发生后,后面的事件处理函数就不会被调用了。应该像下面这样:
if(this.ServiceListChanged != null)
{
object[] args = new object[2] ;
args[0] = this.fsConfiguration.ServerID ;
args[1] = this.GetServiceList() ;
foreach(Delegate del in this.ServiceListChanged.GetInvocationList())
{
try
{
del.DynamicInvoke(args) ;
}
catch(Exception ee)
{
ee = ee ;
//log
}
}
}
{
object[] args = new object[2] ;
args[0] = this.fsConfiguration.ServerID ;
args[1] = this.GetServiceList() ;
foreach(Delegate del in this.ServiceListChanged.GetInvocationList())
{
try
{
del.DynamicInvoke(args) ;
}
catch(Exception ee)
{
ee = ee ;
//log
}
}
}
如果你遇到过的问题,这里没有列出来,请留言和我讨论:)
- Remoting Event 远程事件
- C# Remoting Event 远程事件总结
- Remoting远程处理事件调用的问题
- Remoting 事件
- remoting的远程操作
- [Remoting] 二:远程对象
- [Remoting] 二:远程对象
- Remoting远程Client
- Java Remoting远程服务
- remoting教学三:remoting的远程对象
- 事件Event
- event事件
- event事件
- 事件(event)
- 事件(event)
- Event事件
- event 事件
- 事件event
- 企业(分布式)计算十大谬误
- 插件的“动态替换”
- RSS 实现
- 使用 AOP 陷阱之一
- 组件设计实战--组件之间的关系 (Event、依赖倒置、Bridge)
- Remoting Event 远程事件
- 分页管理器实现
- 动态调用web服务
- 使用 EmptyClass 避免条件判断
- Effective C# 精髓 (待续)
- 开始学习spring.net
- 某公司的一道机考题的解答
- 路径规划(最短路径)算法C#实现
- 推荐所有的.NET开发人员阅读《J2EE Development without EJB》