我可以在WPF应用程序中减少手写笔/触摸输入的开销吗

本文关键字:触摸 输入 开销 手写笔 WPF 应用程序 我可以 | 更新日期: 2023-09-27 18:20:27

我逐渐意识到,在WPF应用程序中,使用触摸屏(生成手写笔和触摸事件而不仅仅是鼠标事件的触摸屏)似乎会导致UI线程的大量开销。如果我在屏幕上、在应用程序上放置足够多的手指,并在某些机器上移动一点,即使是一个简单的应用程序也可能会停止。从表面上看,这似乎很奇怪,基本上超出了我的控制范围。使用探查器显示,大量时间主要花在StylusLogic/InputManager代码(Windows.Input)和Dispatcher.GetMessage例程上。

对于这类事情,我还没有找到任何"最佳实践",我能找到的最接近的解决方案是完全禁用触摸支持(MSDN:禁用RealTimeStylus),并自己挂接WM_touch消息,生成我自己的PreviewTouchDown/PreviewMouseDown事件(在这里有点像"另一种WPF唯一的方式"下描述的:CodeProject:WPF和多点触摸),但这有时也有自己的问题,我觉得这不是一个长期明智的解决方案。我还尝试将事件标记为早期处理的事件,以防止它们挖掘/冒泡;我将每个PreviewStylusMove事件(最频繁的事件)标记为在主窗口视图中处理的实验,这似乎并没有带来巨大的好处。虽然上面的代码项目链接表明WPF中存在(或现在存在)多点触摸的错误,但我发现,即使是在功能不如我的开发人员设置的PC上进行单点触摸(使用我使用的一些实际业务软件),每次也会滞后和停滞数秒,并且您仍然可以使用任务管理器/探查器来观察单点触摸的CPU性能,从而观察到不寻常的工作量。

我能做些什么来减少这些事件的频率吗(例如PreviewStylusMove)?我还有其他选择吗?还是这一切都超出了我的控制范围?

显然,我可以努力提高应用程序的效率,但手写笔/触摸笔似乎是一个巨大的初始性能打击,如果我知道我能做些什么来减轻这种影响,那就太好了。

全面披露:这是一个.NET 4.5应用程序。我在不同型号/品牌的触摸屏上尝试过,没有明显的差异。我的计算机和应用程序的设置期望按住行为与按住鼠标左键相同,而不是生成右键单击事件。我已经在Windows 7和Windows 8.1机器上测试过了,没有任何差异。

下面的例子是我用来测试这个的一个简单应用程序。当我把10根手指放在应用程序窗口上时,它会在我使用过的某些计算机上暂时停止或跳过帧(其他计算机可能太快而无法显示滞后,但在任务管理器之类的计算机中可以观察到负载的增加):

<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应用程序中减少手写笔/触摸输入的开销吗

WPF团队在4.6和4.6.1中进行了一些触摸修复。(我是WPF团队的软件工程师)

做这项工作的工程师在阅读了这个问题后说:*是的,4.6.1本应该对此有很大帮助。*他们还应该确保在触摸事件本身之外进行大量处理,因为这会占用主线程。

4.6.1 2015年10月发布了候选版本。

谢谢,Rob Relyea

http://twitter.com/rrelyea

.NET Framework 4.6.1 RC的发布说明确实声称触摸堆栈性能有所提高。这个描述听起来似乎可以解决这个问题。

触摸堆栈性能得到了改进,在触摸事件中添加了合并支持,使得在UI线程延迟后报告当前位置,类似于鼠标指针移动

http://blogs.msdn.com/b/dotnet/archive/2015/10/29/announcing-net-framework-4-6-1-rc.aspx