2012-11-07 2 views
0

У меня есть приложение WPF, которое подключается к DLL, которую я также пишу. DLL сканирует папку данных стороннего приложения и обрабатывает всю интерпретацию данных внутри. WPF должен предоставить хороший графический интерфейс поверх этого; Я отделил их, потому что в будущем может понадобиться написать для него интерфейс командной строки.C# Serializable Class - WPF MainWindow Exception Occends

Сканирование папки с данными занимает некоторое время, поэтому я хотел сохранить состояние объекта (репозиторий) и открыть его, вместо этого, если папка данных была отсканирована и сохраняет одно и то же состояние «Последнее изменение». Я отметил объект репозитория как [Serializable], однако, когда я пытаюсь сохранить состояние (из WPF или DLL), я получаю исключение, что WPF MainWindow не является [Serializable].

Если я прочитал созданный файл .dat, он имеет некоторую (не уверенную ли все) информацию этого класса.

Я не понимаю, почему он пытался сохранить любую информацию о окнах WPF. Я попытался пометить это окно как [Serializable], чтобы попробовать, однако этот класс не позволяет этого. Поиск в Интернете заставил меня заглянуть в AppDomains, так как я загружаю DLL вместе с приложением, но это немного над моей головой. Ниже приведен пример того, как я сейчас пытаюсь его реализовать. Изменить: вызов serialize находится в нижней части кода WPF.

Следует отметить, что я создал встроенный класс в пространстве имен WPF и смог успешно сериализовать это в файл.

Любая помощь приветствуется.

Это 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 
} 

И 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: И, наконец, исключение:

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: 

ответ

0

Я чувствую себя таким идиотом; Я смог понять это сегодня утром.

Мне пришлось отделить обработчик события ProgressChanged от моего объекта репо.

Он был прикреплен при создании объекта

repo.ProgressChanged += new ProgressChangedEventHandler(repo_ProgressChanged); 

И теперь удалены перед сохранением состояния объекта

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

Надежда, что помогает кому-либо еще, кто работает в том же номере.

0

Я предполагая, что вы используете сериализатор XML. Вы должны показать код сериализации. Также при получении исключения показывайте трассировку исключения и стека. Его гораздо легче определить контекст с этой информацией.

Если это так, вы должны использовать [XmlIgnore], а не атрибут [NonSerialized].

+0

Код сериализации находится внизу кода WPF в методе «SaveRepo». Он использует двоичную сериализацию. Я вставляю исключение в OP. – user1586644