2012-09-25 14 views
6

He estado lidiando con un problema con un backgroundWorker estos últimos días. He estado buscando en foros y documentación en MSDN, pero todavía no he encontrado la respuesta, así que ahora quiero preguntarles gente inteligente.Cargando imágenes en BackgroundWorker

En resumen, tengo un control de usuario personalizado que consiste en un WrapPanel dentro de ScrollViewer. El WrapPanel contiene algunos elementos que se notifican cuando se despliegan a la vista. Se supone que los elementos cargan y muestran una imagen, y aquí es donde entra el problema. Para no bloquear el hilo de la interfaz gráfica de usuario, cargo las imágenes en un BackgroundWorker, pero la GUI se detiene de todos modos. Este es el código de la clase que representa los elementos contenidos en el 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; 
    } 
} 

he añadido algunos comentarios en el código que explica algunas cosas que intenté y lo conduce tengo. Pero lo escribiré de nuevo aquí. Si solo cargo la BitmapImage en backgroundWorker, pero no la utilizo como Fuente de la Imagen en miniatura, la GUI no se detiene (pero obviamente no se muestra ninguna imagen). Además, si configuro la Fuente de la Imagen en miniatura en una BitmapImage estática precargada en el método OnVisibilityGained (Así en el hilo de la GUI), entonces la GUI no se detendrá, por lo que no es la configuración real de Image.Source la culpable.

+0

posible duplicado de [Cargando imagen deja de problema] (http://stackoverflow.com/questions/12103884/loading-image-stops-issue) –

+0

Se bloquea porque ThumbnailImage se actualiza desde su hilo. Id sugerir si tienes una imagen de actualización (BitmapImage i), si invocaste eso con la variable bi, dejaría de estancarse. – BugFinder

+1

@Jason, esa respuesta detalla que la solución es usar BackgroundWorker, esta pregunta detalla problemas usando BackgroundWorker. Claramente, la respuesta a los problemas con BackgroundWorker no puede ser utilizar BackgroundWorker. –

Respuesta

1

Debe hacer uso de la función de informes del backgroundworker que le permite acceder directamente a los controles de su formulario sin invocar.