






















一步一步学Remoting之六:事件(2) 到了午休的时间,抓紧时间继续写,上次说有2个遗留问题:
(1)关闭一个客户端以后会影响其他的客户端事件
原因:客户端没有取消事件订阅就关闭了,触发事件的时候找不到事件订阅者
解决:遍历委托链,找到异常的对象,从委托链中卸下
(2)服务器端对客户端广播,客户端能收到其他客户端的事件处理信息
原因:使用了Singleton模式,共享远程对象
解决:因为需要远程对象有状态且不共享实例,所以只有客户端激活可以选择
修改后的服务端:
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.ApplicationName="RemoteObject.MyObject";
RemotingConfiguration.RegisterActivatedServiceType(typeof(RemoteObject.MyObject));
BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
BinaryClientFormatterSinkProvider clientProvider = new BinaryClientFormatterSinkProvider();
serverProvider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"]=8888;
TcpChannel channel = new TcpChannel(props,clientProvider,serverProvider);
ChannelServices.RegisterChannel(channel);
Console.ReadLine();
}
}
}
using System; namespace RemoteObject
{
[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 string tmp;public int ALongTimeMethod(int a,int b,int time,string ip)
{
Console.WriteLine("来自"+ip+"的异步方法开始");
for(int i=1;i<=10;i++)
{
System.Threading.Thread.Sleep(time);
Console.WriteLine("来自"+ip+"的异步方法完成了"+i*10+"%");
OnMyEvent(new MyEventArgs(i,ip));
}
Console.WriteLine("来自"+ip+"的异步方法结束");
return a+b;
} protected void OnMyEvent(MyEventArgs e)
{
if (MyEvent!=null)
{
foreach(Delegate d in MyEvent.GetInvocationList())
{
try
{
((MyEventHandler)d)(this,e);
}
catch
{
MyEvent-=(MyEventHandler)d;
}
}
}
}
} public class EventClass:MarshalByRefObject
{
public void MyEvent(object sender,MyEventArgs e)
{
if(((MyObject)sender).tmp==e.IP)
Console.WriteLine("异步方法完成了"+e.Rate*10+"%");
}
}
}
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;
static RemoteObject.MyObject app;
static RemoteObject.EventClass ec;
static DateTime dt;
[STAThread]
static void Main(string[] args)
备注:我的所有例子都是在客户端和服务器端部署远程对象的,其实这个做法不是很好,我们应该仅仅把接口部署在两地,远程对象仅仅部署在服务器端即可。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。