ここ数日、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 をロードするだけで、それをサムネイル画像のソースとして適用しない場合、GUI は停止しません (ただし、画像は明らかに表示されません)。また、OnVisibilityGained メソッド (GUI スレッド内) で、thumbnailImage のソースをプリロードされた静的 BitmapImage に設定した場合、GUI は停止しないため、原因は Image.Source の実際の設定ではありません。