在过去的几天里,我一直在处理 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 的源,则 GUI 不会停止(但没有明显显示图像)。此外,如果我在 OnVisibilityGained 方法中将 thumbnailImage 的源设置为一些预加载的静态 BitmapImage(所以在 GUI 线程中),那么 GUI 不会停止,所以不是 Image.Source 的实际设置是罪魁祸首。