我正在开发一个使用 Canvas 显示一些图像(带有一些滤镜效果)的应用程序。
我有一个名为RendererBooster
. 此类的RenderImage()
方法在背景上使用给定的WITH TASKMyViewer
效果渲染图像,并使用渲染图像设置coltrol 的_bSource
属性。(MyViewer 来源于 Canvas)
另一方面,我DispatcherTimer
在MyViewer
课堂上。这每 2 毫秒打勾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 会冻结应用程序。