2015-11-04 10 views
6

Zdałem sobie sprawę, że używanie ekranu dotykowego (takiego, który generuje rysiki & zdarzeń dotykowych, a nie tylko zdarzeń myszy) wydaje się powodować znaczne obciążenie wątku UI w aplikacji WPF. Nawet prosta aplikacja może zostać zatrzymana, jeśli umieściłbym wystarczającą liczbę palców na ekranie, ponad aplikacją i przesunęłaby je nieco na niektórych maszynach. Wydaje się to dość osobliwe i na pierwszy rzut oka, głównie poza moją kontrolą. Korzystanie z profilera ujawniło wiele czasu spędzonego głównie w kodzie StylusLogic/InputManager (Windows.Input) i rutynie Dispatcher.GetMessage.Czy mogę zmniejszyć obciążenie rysika/wejścia dotykowego w aplikacji WPF?

Nie mogłem znaleźć żadnych "najlepszych praktyk" dla tego typu rzeczy, a najbliższym rozwiązaniem, do którego mogłem się przyłączyć, było całkowite wyłączenie obsługi dotykowej (MSDN: Disabling the RealTimeStylus) i samodzielne podłączenie się do wiadomości WM_TOUCH, generowanie własnego podglądu PreviewTouchDown/PreviewMouseDown events (rodzaj opisywanego tutaj w "Another only WPF only way": CodeProject: WPF and multi touch), ale nie jest to bez własnych problemów i nie wydaje mi się rozsądnym rozwiązaniem długoterminowym. Próbowałem także zgłaszać zdarzenia tak wcześnie, aby zapobiec ich tunelowaniu/bulgotaniu; Oznaczyłem każde zdarzenie PreviewStylusMove (najczęstsze zdarzenie) obsługiwane w widoku okna głównego jako eksperyment, co nie przyniosło dużego efektu. Chociaż powyższy odnośnik codeproject stwierdza, że ​​był (lub jest) błąd w WPF dla multi-touch, odkryłem, że nawet pojedynczy dotyk na mniej wydajnym komputerze niż moja konfiguracja programisty (z pewnym oprogramowaniem biznesowym, nad którym pracuję) będzie opóźnij i przeciągnij po kilka sekund, a możesz nadal obserwować niezwykłą ilość pracy za pomocą menedżera zadań/profilera, aby obserwować wydajność procesora za pomocą jednego dotknięcia.

Czy mogę zrobić wszystko, aby zmniejszyć częstotliwość tych zdarzeń (np. PreviewStylusMove)? Czy mam inne opcje, czy to wszystko jest poza moją kontrolą?

Oczywiście, mogę popracować nad ogólną poprawą wydajności aplikacji, ale stylus/touch wydaje się być tak dużym początkowym hitem wydajności, że dobrze byłoby wiedzieć, co mogę zrobić, aby to złagodzić.

Pełne ujawnienie: To jest aplikacja .NET 4.5. Próbowałem tego na różnych modelach/marek ekranu dotykowego bez widocznych różnic. Mój komputer i aplikacja są skonfigurowane z oczekiwaniem, że zachowanie typu "push-and-hold" jest identyczne z przytrzymaniem lewego przycisku myszy, NIE generując zdarzenia typu "kliknij prawym przyciskiem myszy". Przetestowałem to na komputerach z Windows 7 i Windows 8.1 bez żadnych różnic.

Poniższy przykład to prosta aplikacja, której użyłem do przetestowania tego. Kiedy umieścić 10 palców na oknie aplikacji to stragany chwilowo lub pomijanie klatek na niektórych komputerach mam używane (inne mogą być zbyt szybko, aby opóźnienie wejścia ale wzrost obciążenia można zaobserwować w coś takiego menedżera zadań):

<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> 

nie pozostaje na moim komputerze z procesorem 3.4GHz i7-2600, ale robi lag na moim komputerze z procesorem Core 2 Duo 2,93 GHz.

+0

można sprawdzić, czy ten dostaje się lepiej w .Net 4.6? Pamiętam, że słyszałem, że wprowadzili ulepszenia wydajności dla stosu dotykowego w wersji 4.6, ale obecnie nie mogę znaleźć właściwego źródła online. –

+0

Zrobiłem to teraz uruchomić test na kilku maszynach przy użyciu 4.6 i niestety nie, nie było żadnej znaczącej/dostrzegalnej/mierzalnej różnicy od tego, co mogłem powiedzieć. – Rory

+0

+1 dla linku do wyłączania realtimestylus. dla mnie ta krótka metoda wprowadziła wydajność w coś rozsądnego z .NET 3.5. Zgadzam się z @Rory, że nie jest to pełne rozwiązanie, ale na razie jest działającą poprawką. –

Odpowiedz

2

Zespół WPF wprowadził poprawki dotykowe w wersjach 4.6 i 4.6.1. (Jestem inżynierem oprogramowania w zespole WPF)

Inżynier, który wykonał to zadanie, po przeczytaniu tego pytania powiedział: * Tak 4.6.1 powinno to znacznie pomóc. * Powinni także upewnić się, że przetwarzanie odbywa się poza samym dotykiem, ponieważ spowoduje to połączenie głównego wątku.

4.6.1 Kandydat na stanowisko został udostępniony w październiku 2015.

Dzięki Rob Relyea

http://twitter.com/rrelyea

Powiązane problemy