ThreadPool スレッドで作成された BitmapImage インスタンスを使用してイメージを設定しようとすると、「無効なクロススレッド アクセス」例外が発生します。
これを回避するには、UI スレッドで BitmapImage インスタンスを作成する必要があります。しかし、BitmapImage の生成には時間がかかります (100 ミリ秒以上かかります。ここではデモストレーションのためだけにファイルからロードされます)。そのため、ThreadPool スレッドで実行したいと考えています。
UI スレッドで BitmapImage インスタンスをインスタンス化し、ThreadPool スレッドへの参照を渡してそれを操作する場合 (ピクセルの設定など)、UI スレッドにマーシャリングして BitmapImage にアクセスする必要があります。これにより、UI スレッドがフリーズし、まさに私が避けようとしているものです。
提案?
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem((o) =>
{
var bitmapImage = new BitmapImage(new Uri("default.jpg", UriKind.Relative));
TryToSetImage(bitmapImage);
});
}
private void TryToSetImage(object obj)
{
if (this.Dispatcher.CheckAccess())
{
//Exception: The calling thread cannot access this object because a different thread owns it.
image1.Source = obj as BitmapImage;
}
else
{
this.Dispatcher.Invoke(new WaitCallback(TryToSetImage),
System.Windows.Threading.DispatcherPriority.Render,
obj);
}
}