我有一个运行着的IPC服务器,其接口非常简单,目前工作得相当不错。接口本身非常简单,仅由4个方法组成(RemoteCall方法是SingleTone):
[Serializable]
public class NetworkHook : MarshalByRefObject
{
public void onIsInstalled(int pid, MessageDirection direction)
{
}
public void onDataRecieved(int pid, MessageDirection direction, byte[][] data)
{
}
public void onException(int pid, MessageDirection direction, Exception exception)
{
}
public void onPing(int pid, MessageDirection direction)
{
}
}
当我开始为这个类添加事件时(以便服务器的任何部分都可以订阅传入消息,远程调用方法是SingleTone以保持事件监听器),问题就开始了。由于NetworkHook是可序列化的,所以我开始向我的事件添加[field: NonSerialzied]标签。这应该没问题,因为我不需要客户端知道事件监听器(或根本不想知道它们),所以失去它们也没关系:
[field: NonSerialized]
public event EventHandler<InstalledEventArgs> Test;
无论如何,我仍然遇到了这个错误,并尝试了另一种方法,这次使用自定义事件处理程序:
public delegate void HookInstalledEventHandler(object sender, HookInstalledEventArgs args);
[field: NonSerialized]
public event HookInstalledEventHandler Test;
而且 - 当我添加监听器到事件时,仍然会出现异常。所以我尝试重写NetworkHook类的序列化方法:
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
}
由于我没有需要保存的变量,这个问题很简单。但是,我仍然会遇到异常。
现在我已经没有任何想法可以防止这种异常,或者我在这里做错了什么(将事件设置为静态是我真的不想选择的一个选项)。
我收到的异常信息:
System.Runtime.Serialization.SerializationException wurde nicht behandelt.
Message="Der Typ \"SimpleHookGUI.CommandLineReporter\" in Assembly \"SimpleHookGUI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\" ist nicht als serialisierbar gekennzeichnet."
Source="mscorlib"
StackTrace:
Server stack trace:
bei System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
bei System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
bei System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
bei System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
bei System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
bei System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
bei System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
bei System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SerializeMessage(IMessage msg, ITransportHeaders& headers, Stream& stream)
bei System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)
Exception rethrown at [0]:
bei System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
bei System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
bei HookManager.NetworkObserver.NetworkHook.add_Test(HookInstalledEventHandler value)
bei SimpleHookGUI.Program.Main() in xxx\Program.cs:Zeile 24.
bei System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart()
InnerException:
我尝试了第一个答案:
[field: NonSerialized]
private event EventHandler<HookInstalledEventArgs> test;
public event EventHandler<HookInstalledEventArgs> Test
{
add { this.test = (EventHandler<HookInstalledEventArgs>) Delegate.Combine(this.test, value); }
remove { this.test = (EventHandler<HookInstalledEventArgs>) Delegate.Remove(this.test, value); }
}