2016-12-08 2 views
0

Ich bin auf ein Problem gestoßen, das ich nicht herausfinden kann, wie man löst, also beginne ich zu denken, dass ich den BackgroundWorker nicht richtig verstehe.Mit einem BackgroundWorker eine Serialisierungsmethode aufrufen

Ich versuche, einen BackgroundWorker zu verwenden, um die Funktion zum Speichern/Laden in meinem Programm zu behandeln, was bedeutet, dass der Worker die von mir erstellten Serialisierungsmethoden aufrufen soll.

Die Serialisierungsmethode nimmt ein POCO und XML serialisiert es. Dieses POCO enthält mehrere Eigenschaften und eine davon ist vom Typ Brush.

public Brush ShapeColor{ get; set; } 

Ich möchte die Farbe serialisiert werden, aber da ich keinen Pinsel serialisieren kann, ich habe eine unterstützende Eigenschaft gemacht:

public Color StoreColor 
{ 
    get 
    {   
     g = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).G; 
     r = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).R; 
     b = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).B;   
     return Color.FromRgb(r, g, b); 
    } 
    set {} 
} 

Dies funktioniert ohne die Verwendung eines BackgroundWorker. Aber sobald ich versuche, den Methodenaufruf an das Serialisierungsmethode im doWork Verfahren zu machen, wird eine Ausnahme geworfen:

Der aufrufende Thread dieses Objekt nicht zugreifen, da ein anderer Thread es besitzt.

Auf diese:

g = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).G; 
r = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).R; 
b = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).B; 

Mein Verständnis ist, dass ein BackgroundWorker unter Verwendung des Serialisierungsmethode von einem anderen Thread als dem UI-Thread zu nennen, ich verletzen die Regel, die besagt, dass ein Arbeitnehmer nicht UI-Elemente zugreifen können.

Um ehrlich zu sein bin ich nicht ganz sicher, wie ich meine Frage formulieren soll, aber ist es mir nicht möglich, diese POCO's nur von einem Arbeiter zu serialisieren? Hat es etwas damit zu tun, dass die ShapeColor ein Pinsel ist?

Vielen Dank im Voraus und sorry für meine schlechte Erklärung :)

EDIT: die XML-Serialisierung Methode der Veröffentlichung.

public static void convertToXML<T>(T objectToSave, string path) where T : new() 
    { 
     StreamWriter streamWriter = null; 
     try 
     {    
      XmlSerializer serializer = new XmlSerializer(typeof(T)); 
      streamWriter = new StreamWriter(path, false);    

      XmlWriterSettings settings = new XmlWriterSettings() 
      { 
       Indent = true, 
       OmitXmlDeclaration = true, 
      }; 
      serializer.Serialize(streamWriter, objectToSave); 

     } 
     finally 
     { 
      // Close writer 
      if (streamWriter != null) 
      { 
       streamWriter.Close(); 
      } 
     } 
    } 
+0

Versuchen 'zu überprüfen' 'Thread.CurrentThread.ManagedThreadId''', wenn Sie die Erstellung' '' ShapeColor''' und wenn es hier zugreifen. – tym32167

+1

GDI-Objekte wie Pinsel sind nicht nur Datenstrukturen, sie sind an den UI-Thread gebunden. Sie * können * nicht * eine BGW hierfür verwenden. BGW ist veraltet und für das asynchrone Speichern völlig unnötig. Sie können die asynchronen Methoden von z. B. FileStream verwenden, um Daten asynchron zu speichern. –

+0

Bitte senden Sie Ihren * Serialisierungscode *.Der Code, den Sie gepostet haben, verursacht weder das Problem, noch kann es geändert werden, um es zu beheben –

Antwort

0

Sie sind in Freezable Objekte gelaufen.

Diese Objekte können nur in der Regel in einem Unfrozen Zustand aus dem Thread behandelt werden, der sie erstellt hat (was in Ihrem Fall der Thread ist).

Um sie (und nicht zu manipulieren) auf einem anderen Thread zu handhaben, müssen Sie entweder sie Freeze() und sie dann an den anderen Thread übergibt oder den Anruf tätigen auf dem Dispatcher Faden Dispatcher.Invoke().

int r =0; 
int g =0; 
int b =0; 
//Marshalls back to UI thread 
Dispatcher.Invoke(()=>{ 
r = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).R; 
g = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).G; 
b = ((Color)ShapeColor.GetValue(SolidColorBrush.ColorProperty)).B; 
}); 
//Creates object on BGW thread and can be safely used for serialization 
return Color.FromRgb(r, g, b); 
+0

Also habe ich deine Lösung versucht es funktioniert :)! Allerdings muss ich stattdessen 'Application.Current.Dispatcher.Invoke ..' verwenden. Ich weiß nicht, ob das aber in Ordnung ist? – ElloU

+0

Es ist in Ordnung, zu tun, da es im Allgemeinen nur einen Dispatcher pro Anwendung gibt. Sie können mehrere Dispatcher haben, aber es ist eine spezielle, fortgeschrittene Aufgabe. Bitte denken Sie daran, als Antwort zu markieren. :) – toadflakz