2012-09-25 11 views
6

Ich habe in den letzten Tagen mit einem Problem mit einem Hintergrundarbeiter beschäftigt. Ich habe durch Foren und Dokumentation auf MSDN gesucht, habe aber immer noch keine Antwort gefunden. Jetzt möchte ich Sie clevere Leute fragen.Laden von Bildern in BackgroundWorker

Lange Rede kurzer Sinn, ich habe eine benutzerdefinierte Benutzersteuerung, bestehend aus einem WrapPanel in einem ScrollViewer. Das WrapPanel enthält einige Elemente, die benachrichtigt werden, wenn sie in die Ansicht gescrollt werden. Die Elemente sollen dann ein Bild laden und anzeigen, und hier kommt das Problem ins Spiel. Um den GUI-Thread nicht zu sperren, lade ich die Bilder in einen BackgroundWorker, aber die GUI bleibt trotzdem stehen. Dies ist der Code für die Klasse, die die Elemente in der WrapPanel enthaltenen darstellt:

class PictureThumbnail : INotifyingWrapPanelElement 
{ 
    private string path; 
    private Grid grid = null; 

    private BackgroundWorker thumbnailBackgroundCreator = new BackgroundWorker(); 
    private delegate void GUIDelegate(); 
    private Image thumbnailImage = null; 

    public PictureThumbnail(String path) 
    { 
     this.path = path; 
     visible = false; 
     thumbnailBackgroundCreator.DoWork += new DoWorkEventHandler(thumbnailBackgroundCreator_DoWork); 

    } 

    void thumbnailBackgroundCreator_DoWork(object sender, DoWorkEventArgs e) 
    { 
     BitmapImage bi = LoadThumbnail(); 
     bi.Freeze(); //If i dont freeze bi then i wont be able to access 

     GUIDelegate UpdateProgressBar = delegate 
     { 
      //If this line is commented out the GUI does not stall. So it is not the actual loading of the BitmapImage that makes the GUI stall. 
      thumbnailImage.Source = bi; 
     }; 
     grid.Dispatcher.BeginInvoke(UpdateProgressBar); 
    } 


    public void OnVisibilityGained(Dispatcher dispatcher) 
    { 
     visible = true; 
     thumbnailImage = new Image(); 
     thumbnailImage.Width = 75; 
     thumbnailImage.Height = 75; 

     //I tried setting the thumbnailImage.Source to some static BitmapImage here, and that does not make the GUI stall. So it is only when it is done through the GUIDelegate for some reason. 
     grid.Children.Add(thumbnailImage); 
     thumbnailBackgroundCreator.RunWorkerAsync(); 
    } 



    private BitmapImage LoadThumbnail() 
    { 
     BitmapImage bitmapImage = new BitmapImage(); 

     // BitmapImage.UriSource must be in a BeginInit/EndInit block 
     bitmapImage.BeginInit(); 
     bitmapImage.UriSource = new Uri(path); 
     bitmapImage.DecodePixelWidth = 75; 
     bitmapImage.DecodePixelHeight = 75; 
     bitmapImage.EndInit(); 

     return bitmapImage; 
    } 
} 

ich einige Kommentare im Code hinzugefügt haben einige Dinge zu erklären Ich habe versucht, und was führt die ich habe. Aber ich werde es hier nochmal schreiben. Wenn ich BitmapImage nur im backgroundWorker geladen habe, aber nicht als Quelle für das ThumbnailImage, wird die GUI nicht angehalten (aber offensichtlich wird kein Bild angezeigt). Auch wenn ich die Quelle von thumbnailImage auf einige vorinstallierte statische BitmapImage in der OnVisibilityGained-Methode (also im GUI-Thread) setze, wird die GUI nicht angehalten, so dass nicht die tatsächliche Einstellung der Image.Quelle der Schuldige ist.

+0

möglich Duplikat von [Lade Bild stoppt Problem] (http://stackoverflow.com/questions/12103884/loading-image-stops-issue) –

+0

Es hält an, weil ThumbnailImage von Ihrem Thread aktualisiert wird. Id schlägt vor, wenn Sie ein updateImage (BitmapImage i) hätten, wenn Sie das mit der bi-Variable aufgerufen hätten, würde es nicht mehr anhalten. – BugFinder

+1

@Jason, diese Antwort Details, die die Lösung ist, um BackgroundWorker zu verwenden, diese Frage beschreibt Probleme mit BackgroundWorker. Natürlich kann die Antwort auf Probleme mit BackgroundWorker nicht die Verwendung von BackgroundWorker sein. –

Antwort

1

Sie sollten die Berichtsfunktion des Backgroundworker verwenden, mit der Sie ohne Aufruf direkt auf die Steuerelemente Ihres Formulars zugreifen können.