Canvas を使用していくつかの画像 (いくつかのフィルター効果付き) を表示するアプリを開発しています。
という静的クラスがありますRendererBooster。このクラスのRenderImage()メソッドは、背景にWITH TASKMyViewerを指定して画像をレンダリングし、レンダリングされた画像でcoltrol の_bSourceプロパティを設定します。( MyViewer は Canvas から派生しています)
一方、私はクラスのDispatcherTimer中にいます。MyViewerこれは 2ms ごとにDispatcherTimesティックし、NOT NULLかどうかをチェックし、Canvas のメソッドを呼び出します。_bSourceInvalidateVisual()
ここまでは大丈夫です。
私のオーバーライドされたOnRender()メソッドは、それ_bSourceを画面に描画し_bSourceて NULL に設定するだけです。その後、Cannot use a DependencyObject that belongs to a different thread than its parent Freezable例外が発生します。ここにいくつかのサンプルコードがあります。修正するにはどうすればよいですか?
レンダラーブースター
public static class RendererBooster
{
public static void RenderImage()
{
MyViewer viewer = ViewerManager.GetViewer();
Task.Factory.StartNew(() =>
{
unsafe
{
// render
// render again
// render again ..
// ...
// when rendering is done, set the _bSource.
viewer._bSource = BitmapSource.Create(sizeDr.Width, sizeDr.Height, 96, 96, PixelFormats.Prgba64, null, mlh.Buffer, sStride * sizeDr.Height, sStride);
}
});
}
}
マイビューアー
public class MyViewer : Canvas
{
public BitmapSource _bSource = null;
private object _lockObj = new object();
public MyViewer()
{
DispatcherTimer dt = new DispatcherTimer();
dt.Interval = TimeSpan.FromMilliseconds(2);
dt.Tick += dt_Tick;
dt.Start();
}
void dt_Tick(object sender, EventArgs e)
{
if (_bSource == null)
return;
InvalidateVisual();
}
protected override void OnRender(DrawingContext dc)
{
lock (_lockObj)
{
dc.DrawImage(_bSource, new System.Windows.Rect(new System.Windows.Point(0, 0), new System.Windows.Size(ActualWidth, ActualHeight)));
_bSource = null;
// this is the line that i get the exception
//Cannot use a DependencyObject that belongs to a different thread than its parent Freezable
}
}
}
注:他の関数/クラスでレンダリング作業を行っているのはなぜですか? レンダリングには 3 ~ 4 秒かかるためです。OnRender() メソッド内でレンダリングすると、UIThread によってアプリケーションがフリーズします。