在Remoting中客户订阅服务端的事件,如果客户端异常退出,这时在服务端的事件就出错。我的解决办法是逐个调用客户端的处理函数,如果发生异常则中委托链表中删除该函数。由于每个远程事件都要这样的处理,所以我想写一个通用的函数。现在的问题是不能将客户从事件中移除。public static void InvokeDelegate(System.Delegate md,params object[] o)
{
System.Delegate[]dels=md.GetInvocationList();
for(int i=0;i<dels.Length;i++)
{
try
{
dels[i].DynamicInvoke(o);
}
catch
{
System.MulticastDelegate.RemoveAll(md,dels[i]);
}
}
}问题出在函数的签名void InvokeDelegate(System.Delegate md,params object[] o)如果改为下面代码就不会有问题
public static void InvokeDelegate(ref EventHandler md,params object[] o)
{
System.Delegate[]dels=md.GetInvocationList();
for(int i=0;i<dels.Length;i++)
{
try
{
dels[i].DynamicInvoke(o);
}
catch
{
md-=(System.EventHandler)dels[i];
}
}
}如果这样写就必须为每个事件一个这样的函数了....
{
System.Delegate[]dels=md.GetInvocationList();
for(int i=0;i<dels.Length;i++)
{
try
{
dels[i].DynamicInvoke(o);
}
catch
{
System.MulticastDelegate.RemoveAll(md,dels[i]);
}
}
}问题出在函数的签名void InvokeDelegate(System.Delegate md,params object[] o)如果改为下面代码就不会有问题
public static void InvokeDelegate(ref EventHandler md,params object[] o)
{
System.Delegate[]dels=md.GetInvocationList();
for(int i=0;i<dels.Length;i++)
{
try
{
dels[i].DynamicInvoke(o);
}
catch
{
md-=(System.EventHandler)dels[i];
}
}
}如果这样写就必须为每个事件一个这样的函数了....
解决方案 »
- winform中的PropertyGrid怎么添加Event属性页?
- 如何在C#中实现一个托盘的程序?(需要源码)
- 请教大家一个关于呼叫中心的问题!
- 用C#生成Word文档时报出检索COM 类工厂中CLSID 为..的组件时失败
- 关于项目转换的问题
- 乍么使用XtraGrid呀?
- 求救!!!在.NET(c#)应用程序中添加拼写和语法检查功能
- dataset里面有一个数据表,然后……
- 请问,如何才可以得到已经登记到本机的用户的密码???
- 跪求大佬,IIS突然报http-500
- 跪求:输入一个数字判断它是否为斐波那契数
- WINFORM中,用DataGridView绑定数据后,对中间的一列的显示格式进行修改
===================================================
一个通用委托,在每个事件绑定就可以了阿如果没有特殊传递参数的话。。
===================================================
技术交流不该有界限 资源共享不该有条件
博客空间:http://blog.csdn.net/lovingkiss
资源下载:http://download.csdn.net/user/lovingkiss
Email:loving-kiss@163.com
本人说明:<我的帖子我做主,结贴率保持100%>
1、欢迎一切问题有关的交流——无论答案对错;
2、不欢迎 顶、Mark、支持之类口水混分的人;
我保留对非<散分贴>蹭分者的厌恶和鄙视...
精通:jīnɡtōnɡ对学问技术等透彻的了解并熟练掌握
所以,我没有精通,只有JZ
===================================================
{
System.Delegate[]dels=md.GetInvocationList();
for(int i=0;i<dels.Length;i++)
{
try
{
dels[i].DynamicInvoke(o);
}
catch
{
//这样可以不?
md = System.MulticastDelegate.Remove(md,dels[i]);
}
}
}
但它就像struct那样,值是固定的.
你可以把一个Delegate通过组合,分离成另外的Delegate
但你不能修改它.
所以,你只能修改引用.你的问题出在ref上.
因为ref所指定的字段或变量,是必须类型对应的.我给你的建议是把ref改为:public static Delegate Invoke(Delegate list,params object[] args)
{
....
list=Delegate.Remove(list,detachedClient);
return list;
}
Delegate.RemoveALL()----从一个委托的调用列表中移除另一个委托的所有调用列表。看不太明白,测试也没有发现它们的区别。谁能帮我解释一下?
Delegate.Remove (MyDelegate, MyDelegate2 ); 的时候,它把最后那一个除去,变成:MyDelegate1 <-- MyDelegate2 <-- MyDelegate3 <-- MyDelegate4 <-- MyDelegate5这就是"移除另一个委托的最后一个调用列表"的意思.至于Delegate.RemoveAll (MyDelegate, MyDelegate2 ); 就把从MyDelegate 中所有的MyDelegate2 都除去,变成:MyDelegate1 <-- MyDelegate3 <-- MyDelegate4 <-- MyDelegate5说到这里,LZ是如果要把发生异常的委托从链表中删除, 还是应该用RemoveAll ,这样一来如果那个异常的委托函数在链表包含多个的时候可以全部删除. 象这样:public static void InvokeDelegate(System.Delegate md,params object[] o)
{
System.Delegate[]dels=md.GetInvocationList();
for(int i=0;i<dels.Length;i++)
{
try
{
dels[i].DynamicInvoke(o);
}
catch
{
//从md中全部删除发生异常的dels[i]委托,然后更新md.
md = System.MulticastDelegate.RemoveAll(md,dels[i]);
}
}
}
{
System.Delegate[]dels=md.GetInvocationList();
for(int i=0;i<dels.Length;i++)
{
try
{
dels[i].DynamicInvoke(o);
}
catch
{
//从md中删除发生异常的dels[i]委托
md = System.MulticastDelegate.Remove(md,dels[i]);
}
}
}
不过需要注意的是 md = System.MulticastDelegate.Remove(md,dels[i]);确实不能带回新的委托链表,这一点已经才程序中得到证实。用ref也不行,正如 Lostinet(Hello)所说“ref所指定的字段或变量,是必须类型对应的”我的解决方法是
public static Delegate InvokeDelegate(Delegate md,params object[] o)