在 wpf 调试过程中,处理 dispatchertimer 定时器的执行时,缺乏直观的调试方法。本文将介绍如何在 wpf 中调试当前主线程中运行的 dispatchertimer 数量。
在 WPF 中,运行中的 DispatcherTimer 会影响主线程的执行,导致主线程异常忙碌。或者,如果忘记订阅 Tick 事件并设置时间,DispatcherTimer 将持续消耗主线程资源。在没有任何交互时,如果主线程出现卡顿问题,首先应检查是否是 DispatcherTimer 引起的。
以下代码展示了在界面创建一个按钮,点击按钮时会创建并运行一个 DispatcherTimer:
<Grid>
<Button Content="Start Timer" Click="Button_OnClick"/>
</Grid>在 Button_OnClick 方法中添加创建和运行 DispatcherTimer 的代码:
private void Button_OnClick(object sender, RoutedEventArgs e)
{
var dispatcherTimer = new DispatcherTimer()
{
Interval = TimeSpan.FromSeconds(1)
};
dispatcherTimer.Start();
}假设需要调试在进入 Button_OnClick 方法时,当前主线程中有多少个 DispatcherTimer 在运行。可以在该方法上设置断点,如下图所示:

进入 Visual Studio 的监视窗口,输入 System.Windows.Threading.Dispatcher.CurrentDispatcher._timers,即可查看当前主线程中运行的 DispatcherTimer 数量。根据 Dispatcher.CurrentDispatcher 的定义,它是 ThreadStatic 线程静态的,因此调试断点必须设置在主线程执行的代码中。

如果需要进一步了解当前的 DispatcherTimer 是由哪个业务模块定义的,可以通过 Tick 委托找到对应的业务模块,如下图所示:

通过 Tick 委托,可以了解到是哪个类的方法定义了 DispatcherTimer,并通过静态代码找到相应的业务。
如果只想调试 DispatcherTimer 是由哪个业务模块启动创建的,可以设置函数断点。设置函数断点的步骤相对复杂。
在开始之前,需要加载 WindowsBase.dll 的符号。建议使用 .NET Core 或 .NET 5 版本的 WPF 框架进行调试,因为这些版本有源代码支持。在加载 WindowsBase.dll 的符号之前,请从开源的 WPF 项目中将代码拉取到本地。
加载 WindowsBase.dll 符号的方法是在调试 -> 窗口 -> 模块中打开模块窗口,右键点击 WindowsBase.dll 并加载符号。

加载符号时需要网络连接,通常都能成功加载。为什么需要加载 WindowsBase.dll 的符号?因为 System.Windows.Threading.DispatcherTimer 定义在 WindowsBase 程序集中。
接下来,在断点窗口中点击新建函数断点。

输入要调试的函数,例如 System.Windows.Threading.DispatcherTimer.Start,并设置断点。

这样,当触发 DispatcherTimer.Start 函数时,将会进入断点。
进入断点后,系统会提示是否选择源代码,这就是推荐使用开源版本 WPF 框架的原因,因为可以加载相应的文件,实现源代码级别的调试。如果发现源代码有些许不匹配,也无需担心,可以将代码仓库切换到对应的分支或标签,或者取消勾选源代码必须匹配的选项。

通过调用堆栈,可以了解到当前是哪个模块调用了 DispatcherTimer.Start 函数。

以上就是WPF 如何知道当前有多少个 DispatcherTime 在运行的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号