尝试确定 C# WPF 程序中的 FPS

发布于 2024-10-02 04:24:22 字数 232 浏览 5 评论 0原文

我正在使用 WPF 和 C# 编写 触摸表 的应用程序。 (而且,我对 WPF 并不是很熟悉。)我们怀疑我们没有从 API 中获得“请求”的帧速率,因此我尝试编写自己的 FPS 计算器。我知道根据内部时钟计算它的数学方法,我只是不知道如何访问 Windows/WPF API 中的计时器。

我需要什么库/命令才能访问计时器?

I'm writing an application for a touch table using WPF and C#. (And, I'm not terribly familiar with WPF. At all.) We suspect we're not getting the framerate we're "requesting" from the API so I'm trying to write my own FPS calculator. I'm aware of the math to calculate it based on the internal clock, I just don't know how to access a timer within the Windows/WPF API.

What library/commands do I need to get access to a timer?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

高冷爸爸 2024-10-09 04:24:22

尽管您可以使用 DispatcherTimer (它将其滴答声编组到 ui 线程上,从而导致相对性问题)或 System.Threading.Timer (如果您尝试触摸任何 UI 控件,它可能会引发异常),但我建议您只使用使用 WPF 分析工具 :)

Although you could use a DispatcherTimer (which marshalls its ticks onto the ui thread, causing relativity problems), or a System.Threading.Timer (which might throw an exception if you try to touch any UI controls), i'd recommend you just use the WPF profiling tools :)

哑剧 2024-10-09 04:24:22

我认为您正在寻找秒表。只需初始化它并在每次迭代开始时重置它即可。在迭代结束时,进行计算。

I think you're looking for the StopWatch. Just initialize it and reset it with each start of your iteration. At the end of an iteration, do your calculation.

成熟稳重的好男人 2024-10-09 04:24:22

首先,您是否知道 Microsoft 提供了一个免费的诊断工具,可以告诉您 WPF 更新屏幕的帧速率?我想如果您不确信自己获得了所需的帧速率,那么也许您可能不信任它,但我发现它是一个可靠的工具。它称为 Perforator,是 WPF Performance Suite 的一部分,您可以按照此处的说明获取该套件:http: //msdn.microsoft.com/library/aa969767

这可能比自己编写更简单。

另外,您到底是如何“请求”帧速率的?您使用什么 API?您是否使用时间轴的 DesiredFrameRate 属性?如果是这样,则更常用于降低帧速率而不是提高帧速率。 (文档还讨论了提高帧速率以避免撕裂,但这并没有真正意义 - 撕裂是由于呈现与显示器不同步的帧而引起的,并且不是慢帧速率的产物。在任何情况下,在 Vista 或 Windows 7 上,启用 DWM 后不会出现撕裂现象。)这只是一个提示,WPF 不承诺匹配建议的帧速率。

至于测量技术,您可以采用多种方法。如果您只是想确定帧速率是否在正确的范围内,则只需每帧增加一次计数器(通常在 CompositionTarget.Rendering 的事件处理程序中执行此操作) ),并设置一个 DispatcherTimer 每秒触发一次,并让它在 UI 中显示该值,然后重置计数器。它会有些粗糙和准备,因为 DispatcherTimer 并不完全准确,但它会向您显示,例如,当您期望 30fps 时,您是否达到了 15fps。

如果您想获得更精确的视图(例如,您想尝试确定帧是否不断渲染,或者您似乎不时丢失帧),那么情况会变得更加复杂。但在提出更多建议之前,我会先看看 Perforator 是否能满足您的需要。

First of all, are you aware that Microsoft provides a free diagnostic tool that will tell you the frame rate at which WPF is updating the screen? I guess if you're not convinced you're getting the framerate you're asking for, then perhaps you might not trust it, but I've found it to be a reliable tool. It's called Perforator, and it's part of the WPF Performance Suite, which you can get by following the instructions here: http://msdn.microsoft.com/library/aa969767

That's probably simpler than writing your own.

Also, how exactly are you "requesting" a frame rate? What API are you using? Are you using the Timeline's DesiredFrameRate property? If so, this is more commonly used to reduce the frame rate than increase it. (The docs also talk about increasing the frame rate to avoid tearing, but that doesn't really make sense - tearing is caused by presenting frames out of sync with the monitor, and isn't an artifact of slow frame rates. In any case, on Vista or Windows 7, you won't get tearing with the DWM enabled.) It's only a hint, and WPF does not promise to match the suggested frame rate.

As for the measurement technique, there are a number of ways you could go. If you're just trying to work out whether the frame rate is in the right ballpark, you could just increment a counter once per frame (which you'd typically do in an event handler for CompositionTarget.Rendering), and set up a DispatcherTimer to fire once a second, and have it show the value in the UI, and then reset the counter. It'll be somewhat rough and ready as DispatcherTimer isn't totally accurate, but it'll show you whether you've got 15fps when you were expecting 30fps, for example.

If you're trying to get a more precise view (e.g., you want to try to work out whether frames are being rendered constantly, or if you seem to be getting lost frames from time to time), then that gets a bit more complex. But I'll wait to see if Perforator does the trick for you before making more suggestions.

静若繁花 2024-10-09 04:24:22

您想要通过使用 p/Invoke 来包装通常调用的 win32 计时调用(例如 QueryPerformanceCounter ),或者使用 .NET 中已包装它们的内容。

您可以使用 DateTime.Ticks,但它的分辨率可能不够高。 Stopwatch 类在幕后使用 QueryPerformanceCounter。

如果您想要在许多系统上可重复使用的东西,而不是简单的诊断,请注意 QPC 和秒表的处理器相关问题。请参阅这个问题:.NET Stopwatch 类会这么糟糕吗?

You want to either wrap the win32 timing calls you'd normally call (such as QueryPerformanceCounter), by using p/Invoke, or use something in .NET that already wraps them.

You could use DateTime.Ticks, but it's probably not high enough resolution. The Stopwatch class uses QueryPerformanceCounter under the covers.

If you want something that's reusable on a lot of systems, rather than a simple diagnostic, be warned about processor related issues w/ QPC and Stopwatch. See this question: Can the .NET Stopwatch class be THIS terrible?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文