Canvas を使用していくつかの画像 (いくつかのフィルター効果付き) を表示するアプリを開発しています。
という静的クラスがありますRendererBooster
。このクラスのRenderImage()
メソッドは、背景にWITH TASKMyViewer
を指定して画像をレンダリングし、レンダリングされた画像でcoltrol の_bSource
プロパティを設定します。( MyViewer は Canvas から派生しています)
一方、私はクラスのDispatcherTimer
中にいます。MyViewer
これは 2ms ごとにDispatcherTimes
ティックし、NOT NULLかどうかをチェックし、Canvas のメソッドを呼び出します。_bSource
InvalidateVisual()
ここまでは大丈夫です。
私のオーバーライドされた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 によってアプリケーションがフリーズします。