2010-06-05 6 views
12

Zuerst muss ich sagen, dass ich mit WPF und C# noob bin. Anwendung: Erstellen Sie Mandelbrot Bild (GUI) My Dispatcher funktioniert perfekt diesen diesen Fall:WPF Dispatcher {"Der aufrufende Thread kann nicht auf dieses Objekt zugreifen, da ein anderer Thread es besitzt."}

private void progressBarRefresh(){ 

     while ((con.Progress) < 99) 
     { 
      progressBar1.Dispatcher.Invoke(DispatcherPriority.Send, new Action(delegate 
       { 
        progressBar1.Value = con.Progress; 
       } 
      )); 
     } 
    } 

ich die Nachricht (Titel) erhalten, wenn Tring dies mit dem folgenden Code zu tun:

bmp = BitmapSource.Create(width, height, 96, 96, pf, null, rawImage, stride); 

this.Dispatcher.Invoke(DispatcherPriority.Send, new Action(delegate 
      {      
       img.Source = bmp; 
       ViewBox.Child = img; //vllt am schluss 
      } 
     )); 

I werde versuchen zu erklären, wie mein Programm funktioniert. Ich habe einen neuen Thread (weil GUI nicht reagieren) für die Berechnung der Pixel und der Farben erstellt. In diesem Thread (Methode) verwende ich den Dispatcher, um mein Bild in der ViewBox zu aktualisieren, nachdem die Berechnungen fertig sind.

Wenn ich die Berechnung nicht in einen separaten Thread setze, kann ich mein Image aktualisieren oder erstellen.

Antwort

2

Sie erstellen die Bitmap (bmp10) in Ihrem Worker (?) -Thread und übergeben sie dann an den UI-Thread - das ist fehlgeschlagen.

Sie müssen das Bild im UI-Thread erstellen. Sie benötigen wahrscheinlich eine Möglichkeit, auf das Bild, das Sie anzeigen möchten, zu verweisen und die Informationen , an die Benutzeroberfläche zu übergeben.

+1

Sie müssen das Bild nicht im UI-Thread erstellen. Sie können es nur nicht aus einem Thread verwenden, während es auf einem anderen geändert wird (und .NET geht davon aus, dass, wenn Sie es nicht * eingefroren * markieren, es erneut geändert wird). –

2

Sie auch einen Warteschlangenmechanismus passieren Nachrichten zwischen Threads verwenden könnte. So funktioniert die Windows-Architektur. Das macht der Disponent. Sie übergeben einen Verweis an den Delegat, der nicht dem WPF-Thread gehört.

Also ja, Sie haben die Grundidee, aber man braucht, um tatsächlich die Bitmap in dem anderen Thread vorbei Action<T>(T object) verwenden oder in Ihrem Fall:

Dispatcher.Invoke(DispatcherPriority.Send, new Action<Bitmap>(delegate(Bitmap img) { 
    do things here... 
}), bmp); 
+1

Wird keinen Unterschied machen, Sie teilen immer noch das Objekt, auf das verwiesen wird. –

22

Nur im Fall, dass Sie das Objekt zu sein Unter verschiedenen Threads geteilt, erstellen Sie dieses Objekt immer im UI-Thread. Wenn Sie später auf das Objekt zugreifen möchten, können Sie überprüfen, ob Sie Zugriff auf das Objekt haben. Wenn Sie keinen Zugriff haben, rufen Sie die Funktion erneut mit Zugriff auf den UI-Thread auf. Beispiel-Code unten:

private void YourMethod() 
    { 
     if (Application.Current.Dispatcher.CheckAccess()) 
     { 
      // do whatever you want to do with shared object. 
     } 
     else 
     { 
      //Other wise re-invoke the method with UI thread access 
      Application.Current.Dispatcher.Invoke(new System.Action(() => YourMethod())); 
     } 
    } 
2

Wenn Sie eine Dispatcher bekommen erhalten Sie einen anderen für jeden anderen Thread.

this.Dispatcher möglicherweise geben Sie einen anderen Dispatcher nicht die UI, so erhalten Sie diesen Fehler.

Verwenden Sie stattdessen Application.Current.Dispatcher, dies wird immer den Dispatcher des UI-Threads zurückgeben.

Der gleiche Fehler kann passieren, wenn Sie Dispatcher.CurrentDispatcher von einem anderen Thread natürlich verwenden.

Verwandte Themen