我可以减少 WPF 应用程序中 stylus/touch 输入的开销吗?
Can I lessen the overhead of stylus/touch input in a WPF application?
我开始意识到使用触摸屏(生成手写笔和触摸事件而不仅仅是鼠标事件的触摸屏)似乎会导致 WPF 应用程序中 UI 线程的大量开销。如果我将足够多的手指放在屏幕上、应用程序上并在某些机器上稍微移动一下,即使是一个简单的应用程序也会停止运行。这看起来很奇怪,从表面上看,大部分都在我的控制范围之外。使用探查器显示大量时间主要花在 StylusLogic/InputManager 代码 (Windows.Input) 和 Dispatcher.GetMessage 例程上。
对于此类事情,我还没有找到任何“最佳实践”,我能想到的最接近的解决方案是完全禁用触摸支持 (MSDN: Disabling the RealTimeStylus) and hook into WM_TOUCH messages myself, generating my own PreviewTouchDown/PreviewMouseDown events (sort of described here under “Another WPF only way”: CodeProject: WPF and multi touch),但这并非没有有时它自己的问题,并没有让我觉得这是一个长期明智的解决方案。我还尝试将事件标记为早期处理以防止它们 tunnelling/bubbling;我将在主 window 视图中处理的每个 PreviewStylusMove 事件(最频繁的事件)标记为实验,这似乎并没有提供巨大的收益。虽然上面的代码项目 link 指出 WPF 中存在(或存在)多点触控错误,但我发现即使在功能不如我的开发人员设置的 PC 上单点触控(我使用一些实际的商业软件work on) 一次会滞后并停顿几秒钟,您仍然可以使用任务管理器/分析器观察不寻常的工作量,以观察单点触控的 CPU 性能。
我可以做些什么来降低这些事件的频率吗(例如 PreviewStylusMove)?我还有其他选择吗?还是我无法控制?
显然,我可以努力提高应用程序的总体效率,但 stylus/touch 似乎对初始性能造成了很大的影响,因此最好知道我可以做些什么来减轻这种影响.
全面披露:
这是一个 .NET 4.5 应用程序。我已经在不同的 models/brands 触摸屏上尝试过,没有明显的差异。我的计算机和应用程序设置为按下并按住行为与按住鼠标左键相同,而不是生成右键单击事件。我已经在 Windows 7 和 Windows 8.1 机器上测试过了,没有任何区别。
下面的例子是我用来测试的一个简单的应用程序。当我将 10 个手指放在应用程序 window 上时,它会暂时停止或在我使用的某些计算机上跳帧(其他计算机可能太快而无法显示延迟,但可以在任务管理器之类的东西中观察到负载增加):
<Window x:Class="SimpleApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SimpleApplication"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Rectangle Fill="Aqua" Width="150" Height="150" RenderTransformOrigin="0.5, 0.5">
<Rectangle.RenderTransform>
<RotateTransform />
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Rectangle.RenderTransform).(RotateTransform.Angle)"
To="-360"
Duration="0:0:2"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Grid>
在我配备 i7-2600 3.4GHz 处理器的机器上没有延迟,但在我配备 Core 2 Duo 2.93GHz 处理器的机器上确实延迟。
WPF 团队在 4.6 和 4.6.1 中进行了一些触摸修复。 (我是 WPF 团队的一名软件工程师)
做那项工作的工程师在看完这个问题后说:
* 是的,4.6.1 应该有很大帮助。
* 他们还应确保在触摸事件本身之外完成繁重的处理,因为这会占用主线程。
4.6.1 候选版本已于 2015 年 10 月发布。
谢谢,Rob Relyea
.NET Framework 4.6.1 RC 的发行说明确实声称触摸堆栈性能已得到改进。描述听起来像是解决了这个问题。
Touch stack performance has been improved with coalescing support added to touch events such that current position is reported after a UI thread delay similar to mouse pointer movements
http://blogs.msdn.com/b/dotnet/archive/2015/10/29/announcing-net-framework-4-6-1-rc.aspx
我开始意识到使用触摸屏(生成手写笔和触摸事件而不仅仅是鼠标事件的触摸屏)似乎会导致 WPF 应用程序中 UI 线程的大量开销。如果我将足够多的手指放在屏幕上、应用程序上并在某些机器上稍微移动一下,即使是一个简单的应用程序也会停止运行。这看起来很奇怪,从表面上看,大部分都在我的控制范围之外。使用探查器显示大量时间主要花在 StylusLogic/InputManager 代码 (Windows.Input) 和 Dispatcher.GetMessage 例程上。
对于此类事情,我还没有找到任何“最佳实践”,我能想到的最接近的解决方案是完全禁用触摸支持 (MSDN: Disabling the RealTimeStylus) and hook into WM_TOUCH messages myself, generating my own PreviewTouchDown/PreviewMouseDown events (sort of described here under “Another WPF only way”: CodeProject: WPF and multi touch),但这并非没有有时它自己的问题,并没有让我觉得这是一个长期明智的解决方案。我还尝试将事件标记为早期处理以防止它们 tunnelling/bubbling;我将在主 window 视图中处理的每个 PreviewStylusMove 事件(最频繁的事件)标记为实验,这似乎并没有提供巨大的收益。虽然上面的代码项目 link 指出 WPF 中存在(或存在)多点触控错误,但我发现即使在功能不如我的开发人员设置的 PC 上单点触控(我使用一些实际的商业软件work on) 一次会滞后并停顿几秒钟,您仍然可以使用任务管理器/分析器观察不寻常的工作量,以观察单点触控的 CPU 性能。
我可以做些什么来降低这些事件的频率吗(例如 PreviewStylusMove)?我还有其他选择吗?还是我无法控制?
显然,我可以努力提高应用程序的总体效率,但 stylus/touch 似乎对初始性能造成了很大的影响,因此最好知道我可以做些什么来减轻这种影响.
全面披露: 这是一个 .NET 4.5 应用程序。我已经在不同的 models/brands 触摸屏上尝试过,没有明显的差异。我的计算机和应用程序设置为按下并按住行为与按住鼠标左键相同,而不是生成右键单击事件。我已经在 Windows 7 和 Windows 8.1 机器上测试过了,没有任何区别。
下面的例子是我用来测试的一个简单的应用程序。当我将 10 个手指放在应用程序 window 上时,它会暂时停止或在我使用的某些计算机上跳帧(其他计算机可能太快而无法显示延迟,但可以在任务管理器之类的东西中观察到负载增加):
<Window x:Class="SimpleApplication.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SimpleApplication"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Rectangle Fill="Aqua" Width="150" Height="150" RenderTransformOrigin="0.5, 0.5">
<Rectangle.RenderTransform>
<RotateTransform />
</Rectangle.RenderTransform>
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="(Rectangle.RenderTransform).(RotateTransform.Angle)"
To="-360"
Duration="0:0:2"
RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Rectangle.Triggers>
</Rectangle>
</Grid>
在我配备 i7-2600 3.4GHz 处理器的机器上没有延迟,但在我配备 Core 2 Duo 2.93GHz 处理器的机器上确实延迟。
WPF 团队在 4.6 和 4.6.1 中进行了一些触摸修复。 (我是 WPF 团队的一名软件工程师)
做那项工作的工程师在看完这个问题后说: * 是的,4.6.1 应该有很大帮助。 * 他们还应确保在触摸事件本身之外完成繁重的处理,因为这会占用主线程。
4.6.1 候选版本已于 2015 年 10 月发布。
谢谢,Rob Relyea
.NET Framework 4.6.1 RC 的发行说明确实声称触摸堆栈性能已得到改进。描述听起来像是解决了这个问题。
Touch stack performance has been improved with coalescing support added to touch events such that current position is reported after a UI thread delay similar to mouse pointer movements
http://blogs.msdn.com/b/dotnet/archive/2015/10/29/announcing-net-framework-4-6-1-rc.aspx