I understand that using a touch screen (one that generates stylus and touch events, not just mouse events) seems to cause significant overhead for the user interface thread in a WPF application. Even a simple application can be stopped if I put enough fingers on the screen above the application and move them a little to certain machines. This seems very peculiar at first glance, mainly beyond my control. Using the profiler showed a lot of time spent mainly in the StylusLogic / InputManager code (Windows.Input) and in the Dispatcher.GetMessage procedure.
I was not able to find any โbest practicesโ for this kind of thing, and the closest solution I could come up with was to completely disable touch support ( MSDN: disable RealTimeStylus ) and connect to WM_TOUCH messages myself, generating my own PreviewTouchDown / events PreviewMouseDown (like the ones described here in the section โAnother way to only WPFโ: CodeProject: WPF and multi touch ), but this time has no problems of its own, and this does not seem to me to be a long-term reasonable solution. I also tried flagging events that were handled early on to prevent them from tunneling / sparging; I marked every PreviewStylusMove event (the most common event), which is treated as an experiment in the main window, and this does not seem to give a huge win. While the codeproject link above states that there was (or is) a bug for multi-touch in WPF, I found that even one touch on a less powerful PC than my developer's setup (with some actual business software over which I work) there will be a lag and a stop for a few seconds at a time, and you can still observe an unusual amount of work with the task manager / profiler to monitor the processor performance with one touch.
Can I do anything to reduce the frequency of these events (EG PreviewStylusMove)? Do I have other options or is it all out of control?
Obviously, I can work on trying to improve the overall performance of the application, but the stylus / touch seems to have such great initial performance that it would be nice to know what I can do to mitigate this.
Full disclosure: This is a .NET 4.5 application. I tried this on different touch screen models / brands without any visible differences. My computer and application are configured with the expectation that the push-and-hold behavior is identical to holding the left mouse button, NOT generating a right-click event. I tested this on both Windows 7 and Windows 8.1 machines without any differences.
The example below is a simple application that I used to test this. When I put 10 fingers in the application window, it instantly stops or skips frames on some computers that I used (others may be too fast to display a delay, but the load increase can be seen in something like a task manager):
<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>
Not far behind my car with a 3.4 GHz i7-2600 processor, but it is behind my car with a 2.93 GHz Core 2 Duo processor.