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

长话短说,我有一个自定义用户控件,该控件由ScrollViewer内部的WrapPanel组成。 WrapPanel包含一些元素,这些元素在滚动到 View 时会得到通知。
然后应该假定元素加载并显示图像,这就是问题所在。为了不锁定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;
    }
}

我在代码中添加了一些注释,解释了我尝试过的一些事情以及导致的问题。但我会在这里再次写。如果我只是将BitmapImage加载到backgroundWorker中,但不将其应用为thumbnailImage的源,则GUI不会停止(但显然不会显示任何图像)。另外,如果我在OnVisibilityGained方法(因此在GUI线程中)中将thumbnailImage的Source设置为一些预加载的静态BitmapImage,则GUI不会停顿,因此不是Image.Source的实际设置才是罪魁祸首。

最佳答案

您应该利用backgroundworker的报告功能,该功能使您无需调用即可直接访问表单的控件。

关于c# - 在BackgroundWorker中加载图像,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12583594/

10-13 03:23