简体   繁体   English

甚至使用[field:NonSerialized]进行序列化异常

[英]Serializationexception even with [field:NonSerialized]

I have an IPC-Server running with some really simply interface which is working quite ok for now. 我有一个IPC-Server运行一些非常简单的界面,现在工作得很好。 The interface itself is really simple and only consists of 4 methods. 界面本身非常简单,只包含4种方法。 (RemoteCall Method is SingleTone): (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)
    {
    }
}

Troubles begun when I started to add events to this class (so any part of the server can subscribe to incoming messages, the remote calling method is SingleTone to keep the eventlisteners). 当我开始向这个类添加事件时开始出现问题(因此服务器的任何部分都可以订阅传入的消息,远程调用方法是SingleTone来保留事件监视器)。 As the NetworkHook is serializable I started to add [field: NonSerialzied] tags to my events. 由于NetworkHook是可序列化的,我开始在我的事件中添加[field:NonSerialzied]标签。 That should be fine as I don't need the clients to be aware of the event-listeners (or don't them want to be at all) so losing them is ok: 这应该没问题,因为我不需要客户端知道事件监听器(或者他们根本不想要这样做)所以丢失它们是可以的:

[field: NonSerialized]
public event EventHandler<InstalledEventArgs> Test;

Anyway I still got this error and tried another approach with a custom eventhandler this time: 无论如何,我仍然遇到此错误,并尝试使用自定义事件处理程序的另一种方法:

public delegate void HookInstalledEventHandler(object sender, HookInstalledEventArgs args);

[field: NonSerialized]
public event HookInstalledEventHandler Test;

And again - i still get the exception when adding listeners to the event. 而且 - 在向事件添加侦听器时,我仍然会遇到异常。 So i tried to override the serialization method of the NetworkHook-Class: 所以我试图覆盖NetworkHook-Class的序列化方法:

public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{ 

}

As I don't have any variables I need to save this is pretty simple. 由于我没有任何变量,我需要保存,这很简单。 But again - I get an exception. 但是再次 - 我得到一个例外。 So now I run out of ideas what I could do prevent this exception, or what do I do wrong here (making the events static is a choice I really don't want to do)? 所以现在我用尽了我可以做的事情来阻止这个异常,或者我在这里做错了什么(让事件静态是一个我真的不想做的选择)?

The exception I get: 我得到的例外:

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: 

I tried this for the first answer: 我尝试了第一个答案:

[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); }
} 

After i tried every way to tell the serialization not to serialize my events but they kept on getting serialized I tried it the other way round - give my class NetworkHook what it wants, a serializable class. 在我尝试各种方式告诉序列化不要序列化我的事件但他们继续进行序列化之后我反过来尝试了 - 给我的类NetworkHook它想要的,一个可序列化的类。
So I created a new Test class called NetworkListener which is serializable but doesn't serialize the events: 所以我创建了一个名为NetworkListener的新Test类,它是可序列化的,但不会序列化事件:

[Serializable]
public class NetworkListener
{
    private static EventHandler<HookInstalledEventArgs> hookInstalled;

    public event EventHandler<HookInstalledEventArgs> HookInstalled
    {
        add { hookInstalled = (EventHandler<HookInstalledEventArgs>) Delegate.Combine(hookInstalled, value); }
        remove { hookInstalled = (EventHandler<HookInstalledEventArgs>) Delegate.Remove(hookInstalled, value); }
    }

    public void onHookInstalled(Object sender, HookInstalledEventArgs args)
    {
        EventHandler<HookInstalledEventArgs> handler = hookInstalled;
        if (handler != null)
        {
            handler(this, args);
        }
    }
}

This class can subscribe to my NetworkHook : MarshalByRefObject without throwing an exception. 这个类可以订阅我的NetworkHook:MarshalByRefObject而不会抛出异常。 I think it really is only a dirty workaround with that static event in there which doesn't bahave static to the outside (beside it's just another class to pass events). 我认为这真的只是一个肮脏的解决方法,那里的静态事件不会向外部静止(除了它只是传递事件的另一个类)。 But I can't make it private only and flag it with [field: NonSerialized()] as it simply looses all callbacks then. 但是我不能只将它设为私有并用[field:NonSerialized()]标记它,因为它只是丢失了所有的回调。 So at least I wanted to get rid of that extra class and include that event-workaround in my original class: 所以至少我想摆脱那个额外的类,并在我的原始类中包含该事件 - 解决方法:

public class NetworkHook : MarshalByRefObject
{
    private static EventHandler<HookInstalledEventArgs> hookInstalled;

    public event EventHandler<HookInstalledEventArgs> HookInstalled
    {
        add { hookInstalled = (EventHandler<HookInstalledEventArgs>) Delegate.Combine(hookInstalled, value); }
        remove { hookInstalled = (EventHandler<HookInstalledEventArgs>) Delegate.Remove(hookInstalled, value); }
    }
    // ....
}

And by surprise - I do get my exception again. 令人意外的是 - 我再次得到了我的例外。 I some kind a have the feeling the MarshalByRefObject completly bypasses my serialization-commands ... somehow. 我有点感觉MarshalByRefObject完全绕过我的序列化命令......不知何故。 Well - this is a really bad solution I think and I'll have to rewrite some other classes to fit in this - but for the first time in hours - it works at all. 嗯 - 这是一个非常糟糕的解决方案我认为,我将不得不重写一些其他类以适应这一点 - 但这是第一次在几个小时 - 它的工作原理。 I anyone has a better solution I'd love to give it another try :) As long I'll stick with my original class calling some "event proxy" which does delegate the real events. 我有人有一个更好的解决方案我想再试一次:)只要我坚持我的原始类调用一些“事件代理”,它会委托真实的事件。

event is just sugar for more complex construct. event对于更复杂的构造而言只是糖。

You need to decompose it for this to work. 您需要对其进行分解才能使其正常工作。

It is equivalent to: 它相当于:

private EventHandler eventField;

public event EventHandler SomeEvent
{
  add { eventfield = Delegate.Combine(eventfield, value); }
  remove { eventfield = Delegate.Remove(eventfield, value); }
}

For serialization to work, you need to apply the NonSerialized attribute to the eventField field. 要使序列化eventField ,您需要将NonSerialized属性应用于eventField字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM