【发布时间】:2016-01-18 18:25:49
【问题描述】:
我想在 WPF 中创建一个用户控件,它可以使用等宽字体绘制一个 n x m 的字符矩阵。 控件将尽快接受字符串[](目标为 60 fps)并将其绘制在屏幕上。
我需要类似于mplayer ascii playback 的性能。
所有字符都使用相同的等宽字体绘制,但根据一定的规则可能有不同的颜色和背景(类似于VS中的语法高亮)。
我已经在 C# WinForms 中毫无问题地实现了该解决方案,并达到了 60 FPS,但是当我想学习如何在 WPF 中执行此操作时,我只发现了几篇描述 WPF 性能问题和冲突信息的文章和帖子。
那么在这种情况下实现最高性能的最佳方法是什么?
我尝试过的一种天真的方法是:
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Random rand = new Random();
public MainWindow()
{
InitializeComponent();
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(1);
timer.Tick += timer_Tick;
timer.Start();
}
string GenerateRandomString(int length)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++)
{
sb.Append(rand.Next(10));
}
return sb.ToString();
}
void timer_Tick(object sender, EventArgs e)
{
myTextBlock.Inlines.Clear();
for (int i = 0; i < 30; i++)
{
var run = new Run();
run.Text = GenerateRandomString(800);
run.Foreground = new SolidColorBrush(Color.FromArgb((byte)rand.Next(256),(byte)rand.Next(256),(byte)rand.Next(256),(byte)rand.Next(256)));
run.Background = new SolidColorBrush(Color.FromArgb((byte)rand.Next(256),(byte)rand.Next(256),(byte)rand.Next(256),(byte)rand.Next(256)));
myTextBlock.Inlines.Add(run);
}
}
}
问题是:你能比在 WPF 中做得更好吗?
附: 是的,我可以直接使用 DirectX,但这个问题是关于 WPF 而不是 DX。
【问题讨论】:
-
考虑到 WPF 是硬件加速的 而 WinForms 不是,你很有机会在 WPF 中实现一些可以满足 60 FPS 要求的东西。 WPF 在后台使用 DirectX(例如,可以在 WPF 中使用 HLSL)。除此之外,您的问题可能过于宽泛。
-
当然最好的方法是首先实际构建它。 然后看看它是否符合你的标准。如果没有,然后提问。像这样,实在是太宽泛了。
-
你怎么知道你有有问题?
-
您的代码示例无助于说明问题。即使暂时忽略一个人是否可以阅读以 60 fps 变化的文本的问题,该代码示例在测量性能方面至少存在两个重大问题:
DispatcherTimer甚至不能可靠地以 60 Hz 触发Tick事件;并且没有更仔细地控制内存分配(例如重用单个固定容量StringBuilder,或者甚至更好地预先计算要显示的所有字符串),您的测试会被 GC 活动混淆。