如果您已经在渲染到WritableBitmap,为什么不在ThreadPool上启动异步任务呢? WritableBitmap支持来自不同线程的更新,请参考
this question或
the class documentation remarks上的信息。或者,如果线程池不适合您,可以直接运行自己的线程。这样,您就可以控制时序,并且除了同步图像之外,不需要依赖UI线程进行其他任何操作。
下面是我刚编写的一些简单示例代码,它应该能让您了解我的意思:
public partial class MainWindow : Window
{
private WriteableBitmap mImage;
private bool mShutdown;
private object mUpdateLock = new object();
private IntPtr mBuffer;
private int mStride;
public MainWindow()
{
InitializeComponent();
mImage = new WriteableBitmap(10, 2, 96, 96, PixelFormats.Bgr32, null);
wImage.Source = mImage;
Closed += delegate {
CompositionTarget.Rendering -= CompositionTarget_Rendering;
lock (mUpdateLock)
{
mShutdown = true;
mImage.Unlock();
}
};
mImage.Lock();
mBuffer = mImage.BackBuffer;
mStride = mImage.BackBufferStride;
CompositionTarget.Rendering += CompositionTarget_Rendering;
UpdateAsync();
}
private void CompositionTarget_Rendering(object sender, EventArgs e)
{
lock (mUpdateLock)
{
mImage.AddDirtyRect(new Int32Rect(0, 0, 10, 2));
mImage.Unlock();
mImage.Lock();
mBuffer = mImage.BackBuffer;
mStride = mImage.BackBufferStride;
}
}
private async void UpdateAsync()
{
int x = 0;
int y = 0;
int color = 0xFF0000;
for (; ;)
{
lock (mUpdateLock)
{
if (mShutdown)
return;
Marshal.WriteInt32(new IntPtr(mBuffer.ToInt64() + x * 4 + y * mStride), color);
}
if (++x == 10)
{
x = 0;
if (++y == 2)
{
y = 0;
color ^= 0xFF00FF;
}
}
await Task.Delay(500).ConfigureAwait(false);
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Thread.Sleep(2000);
}
}
以及相应的 XAML
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Slow" HorizontalAlignment="Left" VerticalAlignment="Top" Click="Button_Click"/>
<Image x:Name="wImage"/>
</Grid>
</Window>