2012-09-25 17 views
6

Ho avuto a che fare con un backgroundWorker in questi ultimi due giorni. Ho cercato attraverso forum e documentazione su MSDN ma non ho ancora trovato la risposta, quindi ora voglio chiederti delle persone intelligenti.Caricamento immagini in BackgroundWorker

Per farla breve, ho un controllo utente personalizzato costituito da un WrapPanel all'interno di un ScrollViewer. WrapPanel contiene alcuni elementi che vengono notificati quando vengono visualizzati nella vista. Si suppone che gli elementi caricino e visualizzino un'immagine, ed è qui che entra in gioco il problema. Per non bloccare il thread dell'interfaccia grafica, carico le immagini in un BackgroundWorker, ma la GUI si blocca comunque. Questo è il codice per la classe che rappresenta gli elementi contenuti nella WrapPanel:

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; 
    } 
} 

Ho aggiunto alcuni commenti nel codice per spiegare alcune cose ho provato e che cosa porta che ho. Ma lo scriverò di nuovo qui. Se ho appena caricato BitmapImage in backgroundWorker, ma non lo applico come Source of the thumbnailImage la GUI non si blocca (ma nessuna immagine viene visualizzata ovviamente). Inoltre, se si imposta Source of the thumbnailImage su un bitmapImage statico precaricato nel metodo OnVisibilityGained (quindi nel thread della GUI), la GUI non si blocca, quindi non è l'impostazione effettiva di Image.Source che è il colpevole.

+0

possibile duplicato di [Caricamento interruzioni immagine problema] (http://stackoverflow.com/questions/12103884/loading-image-stops-issue) –

+0

Si blocca perché ThumbnailImage viene aggiornato dal thread. L'id suggerisce se tu avessi un updateImage (BitmapImage i), se hai invocato quello con la variabile bi, non sarebbe più in grado di fermarsi. – BugFinder

+1

@Jason, la cui risposta indica in dettaglio che la soluzione è utilizzare BackgroundWorker, questa domanda descrive i problemi utilizzando BackgroundWorker. Chiaramente la risposta ai problemi con BackgroundWorker non può essere quella di usare BackgroundWorker. –

risposta

1

È consigliabile utilizzare la funzionalità di reporting del backgroundworker che consente di accedere direttamente ai controlli del modulo senza eseguire il richiamo.