与代表远程处理
Remoting with delegates
在我们的一个应用程序中,我们有一个(现有的)界面,如下所示:
public interface INotify
{
void RegisterNotification(Action<int, string> notification);
}
现在我们要为实现此接口的对象使用 IpcChannels 来实现 "remoting layer"。
我阅读了许多关于远程处理、委托和事件的文章,但无法让测试场景正常工作。大多数示例使用直接在服务器中实现的事件 class,而不是参数中的委托。
有人知道一个工作示例或给我提示吗?
通过创建 "EventSink" 并使用表达式 lambda 重新创建委托。看起来有点复杂,但工作...
事件接收器:
public class GenericEventSink : MarshalByRefObject
{
public event GenericDelegate MessageReceived;
public Type OriginalType { get; }
public GenericEventSink(Delegate original)
{
OriginalType = original.GetType();
MessageReceived += objects =>
{
try
{
return original.DynamicInvoke(objects);
}
catch (Exception ex)
{
return null;
}
};
}
public override object InitializeLifetimeService()
{
return null;
}
public object OnMessageReceived0()
{
return MessageReceived?.Invoke();
}
public object OnMessageReceived1(object o1)
{
return MessageReceived?.Invoke(o1);
}
public object OnMessageReceived2(object o1, object o2)
{
return MessageReceived?.Invoke(o1, o2);
}
public object OnMessageReceived3(object o1, object o2, object o3)
{
return MessageReceived?.Invoke(o1, o2, o3);
}
}
...以及重新创建要调用的委托的方法:
private object UnmarshalDelegate(GenericEventSink generic)
{
var pars = generic.OriginalType.GenericTypeArguments.Select(Expression.Parameter).ToArray();
// create the call
var method = generic.GetType().GetMethod("OnMessageReceived" + pars.Length);
var call = Expression.Call(Expression.Constant(generic), method, pars.Select(p => Expression.Convert(p, typeof(object))));
return Expression.Lambda(generic.OriginalType, call, pars).Compile();
}
在我们的一个应用程序中,我们有一个(现有的)界面,如下所示:
public interface INotify
{
void RegisterNotification(Action<int, string> notification);
}
现在我们要为实现此接口的对象使用 IpcChannels 来实现 "remoting layer"。
我阅读了许多关于远程处理、委托和事件的文章,但无法让测试场景正常工作。大多数示例使用直接在服务器中实现的事件 class,而不是参数中的委托。
有人知道一个工作示例或给我提示吗?
通过创建 "EventSink" 并使用表达式 lambda 重新创建委托。看起来有点复杂,但工作...
事件接收器:
public class GenericEventSink : MarshalByRefObject
{
public event GenericDelegate MessageReceived;
public Type OriginalType { get; }
public GenericEventSink(Delegate original)
{
OriginalType = original.GetType();
MessageReceived += objects =>
{
try
{
return original.DynamicInvoke(objects);
}
catch (Exception ex)
{
return null;
}
};
}
public override object InitializeLifetimeService()
{
return null;
}
public object OnMessageReceived0()
{
return MessageReceived?.Invoke();
}
public object OnMessageReceived1(object o1)
{
return MessageReceived?.Invoke(o1);
}
public object OnMessageReceived2(object o1, object o2)
{
return MessageReceived?.Invoke(o1, o2);
}
public object OnMessageReceived3(object o1, object o2, object o3)
{
return MessageReceived?.Invoke(o1, o2, o3);
}
}
...以及重新创建要调用的委托的方法:
private object UnmarshalDelegate(GenericEventSink generic)
{
var pars = generic.OriginalType.GenericTypeArguments.Select(Expression.Parameter).ToArray();
// create the call
var method = generic.GetType().GetMethod("OnMessageReceived" + pars.Length);
var call = Expression.Call(Expression.Constant(generic), method, pars.Select(p => Expression.Convert(p, typeof(object))));
return Expression.Lambda(generic.OriginalType, call, pars).Compile();
}