gpt4 book ai didi

c# - WPF - 呈现 "Real Time"最佳实践

转载 作者:太空狗 更新时间:2023-10-29 23:31:13 25 4
gpt4 key购买 nike

实现说明:

在每个 CompositionTarget.Rendering 事件中,我使用 Writablebitmap 绘制 4 条相邻的线,(这是“实时”折线图的绘图仪)。

问题:

这很好用,直到 UI 线程似乎很忙,然后是下一个 CompositionTarget.Rendering事件需要更长的时间才能触发。

问题:

是否有某种机制可以保持恒定的渲染间隔,其优先级高于任何其他 UI 操作?

可能的解决方案:

我正在考虑创建一个 HostVisual 以及如何为其分配 DispatcherTimer ,
这种方法行得通吗?

还有其他想到的方法吗?

提前致谢。

最佳答案

如果您已经渲染到 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)
{
// for a large image you can optimize that by only updating the parts that changed,
// collect dirty-areas in a list or something (while under the lock of course!)
mImage.AddDirtyRect(new Int32Rect(0, 0, 10, 2));
mImage.Unlock();
mImage.Lock();

// I don't know if these can changes, but docs say to acquire them after locking ...
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;

// feel free to do 'unsafe' code here if you know what you're doing
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>

关于c# - WPF - 呈现 "Real Time"最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23854176/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com