C# 在BackgroundWorker中加载图像

C# 在BackgroundWorker中加载图像,c#,wpf,backgroundworker,bitmapimage,wrappanel,C#,Wpf,Backgroundworker,Bitmapimage,Wrappanel,这几天我一直在和一个后台工作人员处理一个问题。我一直在浏览有关MSDN的论坛和文档,但仍然没有找到答案,所以现在我想问你们一些聪明的人 长话短说,我有一个自定义用户控件,由ScrollViewer中的一个WrapPanel组成。WrapPanel包含一些元素,这些元素在滚动到视图中时会得到通知。 然后这些元素应该加载并显示一个图像,这就是问题所在。为了不锁定gui线程,我将图像加载到BackgroundWorker中,但gui无论如何都会暂停。这是表示WrapPanel中包含的元素的类的代码:

这几天我一直在和一个后台工作人员处理一个问题。我一直在浏览有关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的源应用,GUI不会停止(但没有明显显示图像)。另外,如果我在OnVisibilityGain方法中将thumbnailImage的源设置为某个预加载的静态BitmapImage(因此在GUI线程中),则GUI不会暂停,因此,这不是图像的实际设置。源代码是罪魁祸首。

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

可能会出现重复,因为ThumbnailImage是从线程更新的。Id建议如果您有一个updateImage(BitmapImage i),如果您使用bi变量调用它,它将停止暂停。@Jason,该答案详细说明解决方案是使用BackgroundWorker,该问题是使用BackgroundWorker详细说明问题。显然,解决BackgroundWorker问题的方法不能是使用BackgroundWorker。@PeterRitchie:是的,你是对的。Lajja Thaker说这个问题是几天前提出的,所以我想我应该以正确的方式链接到这个问题(防止重复),而不仅仅是在答案中链接到这个问题。不幸的是,我在别的事情上被扯了出去,当我回来的时候,我只是把这个问题连在一起,没有读它(假设你和我都是傻瓜……在这种情况下是我)。如果我能收回最后一票,我会的。我想说的是,在我下次盲目尝试帮助别人之前,我一定要认真阅读这个问题。