在BackgroundWorker中加载图像

时间:2012-09-25 13:04:28

标签: c# wpf backgroundworker bitmapimage wrappanel

过去几天我一直在处理backgroundWorker的问题。我一直在浏览MSDN上的论坛和文档,但仍然没有找到答案,所以现在我想问你聪明的人。

长话短说,我有一个自定义用户控件,由ScrollViewer中的WrapPanel组成。 WrapPanel包含一些在滚动到视图时通知的元素。 然后,这些元素将被加载并显示图像,这就是问题所在的地方。为了不锁定gui线程,我将图像加载到BackgroundWorker中,但GUI仍然会停止。这是表示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;
    }
}

我在代码中添加了一些注释,解释了我尝试的一些内容以及我的主要内容。但我会在这里再写一遍。如果我只是在backgroundWorker中加载BitmapImage,但不将它作为thumbnailImage的Source应用,则GUI不会停止(但显然没有显示图像)。此外,如果我在OnVisibilityGained方法中将thumbnailImage的Source设置为某些预加载的静态BitmapImage(那么在GUI线程中),那么GUI将不会停止,因此它不是Image.Source的实际设置,而是罪魁祸首。

1 个答案:

答案 0 :(得分:1)

您应该使用backgroundworker的报告功能,它允许您直接访问表单的控件而无需调用。