简体   繁体   English

c#可序列化类-WPF MainWindow发生异常

[英]c# Serializable Class - WPF MainWindow Exception Occurs

I have a WPF application which is hooking into a DLL that I am also writing. 我有一个WPF应用程序,它正在连接到我也在写的DLL中。 The DLL scans a data folder of a 3rd Party application and handles all the interpretation of data within. DLL扫描第三方应用程序的数据文件夹并处理其中的所有数据解释。 The WPF is to provide a nice GUI on top of that; WPF将在此之上提供一个不错的GUI。 I separated them because it may be necessary in the future to write a command line interface for it too. 我将它们分开是因为将来可能也有必要为其编写命令行界面。

The scanning of the data folder takes some time so I wanted to save the state of the object (a Repository) and open that instead if the data folder has been scanned and retains the same 'Last Modified' state. 扫描数据文件夹需要花费一些时间,因此我想保存对象(存储库)的状态,然后打开该文件夹(如果已扫描数据文件夹并保留相同的“上次修改”状态)。 I have marked the Repository object as [Serializable] however when I attempt to save the state (from either the WPF or the DLL) I get an exception that the WPF MainWindow is not [Serializable]. 我已将Repository对象标记为[Serializable],但是当我尝试保存状态(从WPF或DLL)时,我得到了一个异常,即WPF MainWindow不是[Serializable]。

If I read the created .dat file it does have some (not sure if all) information from that class. 如果我阅读创建的.dat文件,它确实具有该类的一些(不确定是否全部)信息。

I don't understand why it would be trying to save any information about the WPF windows. 我不明白为什么它将尝试保存有关WPF窗口的任何信息。 I have tried to mark the window as [Serializable] just to try however that class does not allow it. 我试图将窗口标记为[Serializable]只是为了尝试但是该类不允许它。 Searching around the web had me looking into AppDomains since I'm loading a DLL along with the application but that is a little over my head. 网上搜索让我调查了AppDomains,因为我正在将DLL和应用程序一起加载,但这有点麻烦。 Below is how I am currently trying to implement it. 以下是我目前尝试实施的方法。 Edit: The call to serialize is at the bottom of the WPF code. 编辑:序列化的调用位于WPF代码的底部。

I should mention that I created an inline class within the WPF namespace and was able to successfully serialize that to a file. 我应该提到,我在WPF名称空间中创建了一个内联类,并且能够成功地将其序列化到文件中。

Any help is appreciated. 任何帮助表示赞赏。

This is the DLL: 这是DLL:

namespace HPOO_XML_Parser
{
[Serializable]
public class HPOORepository
{

    string _version;
    string _path;
    string _library;
    string _uuid;


    [NonSerialized]
    BackgroundWorker bWorker = new BackgroundWorker();
    [NonSerialized]
    XElement _xmlRepo;      


    int _nodeCount;
    List<Node> nodes;
    ...
    Rest of properties and methods
}

And the WPF which calls it 还有WPF

namespace HPOO_Repository_Scanner
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    HPOORepository repo;

    public MainWindow()
    {
        InitializeComponent();
        StatusVisibility(); // Simply hides progress bar/cancel button
    }

    private void OpenRepository(object sender, RoutedEventArgs e)
    {

        string ooHome;
        using (FolderBrowserDialog browser = new FolderBrowserDialog())
        {
            ooHome = Environment.GetEnvironmentVariable("ICONCLUDE_HOME");
            if (ooHome != null)
            {
                browser.SelectedPath = ooHome;
            }
            browser.ShowNewFolderButton = false;
            browser.Description = "Select a repository to open...";

            if (browser.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                try
                {
                    repo = new HPOORepository(browser.SelectedPath);
                }
                catch (Exception ex)
                {
                    System.Windows.MessageBox.Show(ex.Message, "Invalid Repository Selected", MessageBoxButton.OK, MessageBoxImage.Error);

                }
            }
            repo.ProgressChanged += new ProgressChangedEventHandler(repo_ProgressChanged);

            prgStatus.Maximum = 100;

            repo.ReadRepository();

        }

    }
private void mnuSave_Click(object sender, RoutedEventArgs e)
    {
        SaveRepo(repo);
    }

    public void SaveRepo(object repository)
    {
        BinaryFormatter binFormat = new BinaryFormatter();

        using (Stream fStream = new FileStream("test" + ".dat",
            FileMode.Create, FileAccess.Write, FileShare.None))
        {
            binFormat.Serialize(fStream, repository);
        }
    }

Edit: And finally the exception: 编辑:最后是例外:

System.Runtime.Serialization.SerializationException was unhandled
Message=Type 'HPOO_Repository_Scanner.MainWindow' in Assembly 'HPOO Repository Scanner, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.
Source=mscorlib
StackTrace:


    at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type)
       at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context)
       at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
       at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
       at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter)
       at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
       at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)
       at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph)
       at HPOO_Repository_Scanner.MainWindow.SaveRepo(Object repository) in \\tsclient\D\Dropbox\_Work\Visual Studio Projects\HPOO Repository Scanner\HPOO Repository Scanner\HPOO Repository Scanner\MainWindow.xaml.cs:line 179
       at HPOO_Repository_Scanner.MainWindow.mnuSave_Click(Object sender, RoutedEventArgs e) in \\tsclient\D\Dropbox\_Work\Visual Studio Projects\HPOO Repository Scanner\HPOO Repository Scanner\HPOO Repository Scanner\MainWindow.xaml.cs:line 168
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
       at System.Windows.Controls.MenuItem.InvokeClickAfterRender(Object arg)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.DispatcherOperation.InvokeImpl()
       at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
       at System.Threading.ExecutionContext.runTryCode(Object userData)
       at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Windows.Threading.DispatcherOperation.Invoke()
       at System.Windows.Threading.Dispatcher.ProcessQueue()
       at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
       at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg)
       at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
       at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
       at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
       at System.Windows.Threading.Dispatcher.Run()
       at System.Windows.Application.RunDispatcher(Object ignore)
       at System.Windows.Application.RunInternal(Window window)
       at System.Windows.Application.Run(Window window)
       at System.Windows.Application.Run()
       at HPOO_Repository_Scanner.App.Main() in \\tsclient\D\Dropbox\_Work\Visual Studio Projects\HPOO Repository Scanner\HPOO Repository Scanner\HPOO Repository Scanner\obj\x86\Debug\App.g.cs:line 0
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

I'm assuming that you are using the XML serialiser. 假设您正在使用XML序列化器。 You should show the serialising code. 您应该显示序列化代码。 Also when getting an exception, show the exception and stack trace. 同样,在获取异常时,请显示异常和堆栈跟踪。 Its a lot easier to determine context with this info. 确定此信息的上下文要容易得多。

If so, you must use the [XmlIgnore] not the [NonSerialized] attribute. 如果是这样,则必须使用[XmlIgnore]而不是[NonSerialized]属性。

I feel like such an idiot; 我觉得自己是个白痴。 I was able to figure it out this morning. 我能今天上午弄明白。

I had to detach the ProgressChanged event handler from my repo object. 我不得不从我的回购对象中分离ProgressChanged事件处理程序。

It was attached at object creation 它附加在对象创建时

repo.ProgressChanged += new ProgressChangedEventHandler(repo_ProgressChanged);

And now removed before saving the object state 现在在保存对象状态之前将其删除

private void mnuSave_Click(object sender, RoutedEventArgs e)
{
  repo.ProgressChanged -= repo_ProgressChanged;
  SaveRepo(repo);
}

Hope that helps anyone else who runs into the same issue. 希望对其他遇到相同问题的人有所帮助。

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

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