2017-03-03 5 views
0

Ich habe eine einfache Methode, die eine Funktion aufrufen, die ein bitmap Bild zurückgibt.Kann UI von einem anderen Thread in WPF nicht aktualisieren

private void ImageToGrayScale(object sender, RoutedEventArgs e) 
{ 
    pbStatus.Visibility = Visibility.Visible; 
    if (loadedImage != null) 
    { 
     new Thread(() => 
     { 
      BitmapImage bitmapImage= ThreadProcedure(); 
      this.Dispatcher.Invoke(new Action(()=> { 
       pbStatus.Visibility = Visibility.Hidden; 
       EditedImage.Source = bitmapImage; 
      })); 
     }).Start(); 
    } 
    else 
    { 
     MessageBox.Show("Please select the image first!"); 
    } 
} 

Everytime in Zeile: EditedImage.Source = bitmapImage; ein einen Fehler:

The calling thread cannot access this object because a different thread owns it.

Auch hier ist die Methode, die eine bitmap Bild zurückgibt.

private BitmapImage ThreadProcedure() 
{ 
    Bitmap editedImage = new Bitmap(loadedImage); 
    for (int x = 0; x < editedImage.Width; x++) 
    { 
     for (int y = 0; y < editedImage.Height; y++) 
     { 
      Color pixelColor = editedImage.GetPixel(x, y); 
      int rgb = (int)((pixelColor.R + pixelColor.G + pixelColor.B)/3); 
      editedImage.SetPixel(x, y, Color.FromArgb(rgb, rgb, rgb)); // Now greyscale 
     } 
    } 
    return Converter.ConvertBitmapToBitmapImage(editedImage, extension); 
} 
+0

Was ist loadedImage, ist das das Problem? Sie erstellen ein neues Bitmap daraus im Thread-Prozess. Oder vielleicht sollten Sie die BitmapImage als Parameter an den Dispatcher-Delegaten übergeben ... – japesu

+0

Das Problem hier ist am ehesten mit dem "BitmapImage" -Objekt - es ist in einem anderen Thread zum Dispatcher Sync-Kontext erstellt. Wenn Sie also davon lesen und es in die Quelle kopieren, wird dieser Fehler wahrscheinlich nicht angezeigt. Um dies zu testen, verschieben Sie den Aufruf von 'ThreadProcedure' innerhalb des Dispatcher-Aufrufs und sehen Sie, ob es funktioniert. – Baldrick

+0

@Baldrick, es funktioniert, aber es blockiert den UI-Thread und das Fenster reagiert nicht. –

Antwort

1

Sie die BitmapImage durch den Aufruf seiner Freeze() Methode, um sie als die auf einem anderen Thread zu verwenden, um der Lage sein, einfrieren sollte, auf dem es erstellt wurde:

new Thread(() => 
{ 
     BitmapImage bitmapImage = ThreadProcedure(); 
     bitmapImage.Freeze(); //<-- 

     this.Dispatcher.Invoke(new Action(() => { 
      pbStatus.Visibility = Visibility.Hidden; 
      EditedImage.Source = bitmapImage; 
     })); 
}).Start(); 
+0

Ja, das hat funktioniert! Danke vielmals !. –

-1

einen Thread zum Aktualisieren eines Bildes zu schaffen, ist nicht das Beste, was Dispatcher.BeginInvoke stattdessen Gebrauch zu tun, wird dies die Aktion asynchron auszuführen.

"Control.BeginInvoke: Executes on the UI thread, and calling thread doesn't wait for completion."

das Gewindeteil entfernen und diesen Code verwenden das Problem gelöst werden sollte.

  BitmapImage bitmapImage= ThreadProcedure(); 

     Dispatcher.BeginInvoke(DispatcherPriority.Input, new Action(() => 
     { 
      pbStatus.Visibility = Visibility.Hidden; 
      EditedImage.Source = bitmapImage; 
     })); 
+0

Ich habe denselben Fehler bekommen. –

Verwandte Themen