Freigeben über


Das Threadmodell für Freihandeingaben

Einer der Vorteile von Freihandeingaben auf einem Tablet PC ist, dass der Eindruck entsteht, mit einem echten Stift auf Papier zu schreiben. Um dies zu bewerkstelligen, werden vom Tablettstift die Eingabedaten mit einer im Vergleich zu einer Maus wesentlich höheren Rate erfasst und die Freihandeingabe während des Schreibvorgangs gerendert. Der Benutzeroberflächenthread (UI-Thread) der Anwendung ist zum Erfassen der Daten und zum Rendern der Freihandeingabe nicht ausreichend, da er blockiert werden kann. Um dieses Problem zu lösen, werden von einer WPF-Anwendung zwei zusätzliche Threads für die Freihandeingabe verwendet.

In der folgenden Liste werden die Threads erläutert, die am Erfassen und Rendern digitaler Freihandeingaben beteiligt sind:

  • Thread für den Tablettstift (Stiftthread) - In diesem Thread werden die Daten vom Tablettstift erfasst. (Eigentlich handelt es sich um einen Threadpool, in diesem Thema wird er jedoch als einzelner Stiftthread dargestellt.)

  • Thread für die Anwendungsbenutzeroberfläche (UI-Thread) - Von diesem Thread wird die Benutzeroberfläche der Anwendung gesteuert.

  • Thread für das dynamische Rendering (Rendering-Thread) - In diesem Thread wird die Freihandeingabe gerendert, während der Benutzer einen Strich zeichnet. Der Thread für das dynamische Rendering unterscheidet sich von dem Thread, in dem andere Benutzeroberflächenelemente für die Anwendung gerendert werden, wie unter Window Presentation Foundation Threading-Modell erläutert.

Das gleiche Freihandeingabemodell wird verwendet, unabhängig davon, ob von der Anwendung das InkCanvas-Steuerelement oder ein benutzerdefiniertes Steuerelement verwendet wird, vergleichbar mit dem unter Erstellen eines Freihandeingabesteuerelements beschriebenen. In diesem Thema wird Threading in Bezug auf InkCanvas erläutert, die gleiche Konzepte gelten jedoch auch für benutzerdefinierte Steuerelemente.

Übersicht über Threading

Im folgenden Diagramm wird das Threadingmodell beim Zeichnen eines Strichs durch den Benutzer veranschaulicht:

Verkettungsmodell beim Zeichnen eines Strichs.

  1. Auftretende Aktionen während des Zeichnens eines Strichs durch den Benutzer

    1. Wenn der Benutzer einen Strich zeichnet, werden die Tablettstiftpunkte über den Stiftthread erfasst. Von Tablettstift-Plug-Ins, einschließlich DynamicRenderer, werden die Tablettstiftpunkte im Stiftthread angenommen und ggf. bearbeitet, bevor sie von InkCanvas empfangen werden.

    2. Vom DynamicRenderer werden die Tablettstiftpunkte im dynamischen Rendering-Thread gerendert. Dies wird zur gleichen Zeit wie der vorherige Schritt ausgeführt.

    3. Vom InkCanvas werden die Tablettstiftpunkte im UI-Thread empfangen.

  2. Auftretende Aktionen nach dem Zeichnen eines Strichs durch den Benutzer

    1. Nachdem der Benutzer einen Strich gezeichnet hat, wird vom InkCanvas ein Stroke-Objekt erstellt und dem InkPresenter hinzugefügt, von dem es statisch gerendert wird.

    2. Der DynamicRenderer wird vom UI-Thread benachrichtigt, dass der Strich statisch gerendert wird. Die grafische Darstellung des Strichs vom DynamicRenderer wird daraufhin von diesem gelöscht.

Erfassen von Freihandeingaben und Tablettstift-Plug-Ins

Jedes UIElement verfügt über eine StylusPlugInCollection. Von den StylusPlugIn-Objekten in der StylusPlugInCollection werden die Tablettstiftpunkte im Stiftthread empfangen und ggf. bearbeitet. Von den StylusPlugIn-Objekten werden die Tablettstiftpunkte entsprechend ihrer Reihenfolge in der StylusPlugInCollection empfangen.

Im folgenden Diagramm wird Situation angenommen, in der die StylusPlugIns-Auflistung eines UIElement ein stylusPlugin1, einen DynamicRenderer und ein stylusPlugin2 enthält (in dieser Reihenfolge).

Reihenfolge der Tablettstift-Plugins beeinflusst Ausgabe.

Im oben dargestellten Diagramm findet das folgende Verhalten statt:

  1. Von StylusPlugin1 werden die Werte für x und y bearbeitet.

  2. Vom DynamicRenderer werden die bearbeiteten Tablettstiftpunkte empfangen und im dynamischen Rendering-Thread gerendert.

  3. Von StylusPlugin2 werden die bearbeiteten Tablettstiftpunkte empfangen und die Werte für x und y weiter bearbeitet.

  4. Von der Anwendung werden die Tablettstiftpunkte erfasst und der Strich statisch gerendert, nachdem er vom Benutzer gezeichnet wurde.

Angenommen, von stylusPlugin1 werden die Tablettstiftpunkte auf ein Rechteck eingeschränkt und von stylusPlugin2 nach rechts verschoben. Im oben beschriebenen Szenario werden die eingeschränkten Tablettstiftpunkte vom DynamicRenderer empfangen, jedoch nicht die verschobenen Tablettstiftpunkte. Wenn der Benutzer einen Strich zeichnet, wird der Strich innerhalb des Rechtecks gerendert, jedoch solange nicht verschoben, bis der Tablettstift vom Benutzer angehoben wird.

Ausführen von Vorgängen mit einem Tablettstift-Plug-In im UI-Thread

Da eine genaue Trefferüberprüfung im Stiftthread nicht ausgeführt werden kann, werden von einigen Elementen möglicherweise gelegentlich Tablettstifteingaben empfangen, die für andere Elemente vorgesehen sind. Wenn Sie sicherstellen müssen, dass die Eingabe vor dem Ausführen eines Vorgangs korrekt weitergeleitet wurde, abonnieren Sie die folgenden Methoden, und führen Sie den Vorgang in diesen aus: OnStylusDownProcessed, OnStylusMoveProcessed oder OnStylusUpProcessed. Diese Methoden werden vom Anwendungsthread nach der Ausführung einer genauen Trefferüberprüfung aufgerufen. Rufen Sie zum Abonnieren dieser Methoden die NotifyWhenProcessed-Methode in der im Stiftthread ausgeführten Methode auf.

Im folgenden Diagramm sind die Beziehungen zwischen dem Stiftthread und dem UI-Thread hinsichtlich der Tablettstiftereignisse eines StylusPlugIn dargestellt.

Freihandverkettungsmodelle (UI und Stift)

Rendern von Freihandeingaben

Wenn der Benutzer einen Strich zeichnet, wird die Freihandeingabe von DynamicRenderer in einem separaten Thread gerendert, sodass der Tablettstift auch dann für eine Freihandeingabe verwendet werden kann, wenn der UI-Thread ausgelastet ist. Vom DynamicRenderer wird beim Erfassen der Tablettstiftpunkte eine visuelle Struktur im dynamischen Rendering-Thread erstellt. Nachdem der Benutzer den Strich gezeichnet hat, wird vom DynamicRenderer eine Benachrichtigung gefordert, wenn von der Anwendung der nächste Renderingdurchlauf ausgeführt wird. Nachdem die Anwendung den nächsten Renderingdurchlauf ausgeführt hat, wird die visuelle Struktur vom DynamicRenderer gelöscht. Dieser Prozess wird anhand des folgenden Diagramms veranschaulicht.

Freihandverkettungsdiagramm

  1. Der Benutzer beginnt, den Strich zu zeichnen.

    1. Vom DynamicRenderer wird eine visuelle Struktur erstellt.
  2. Der Benutzer zeichnet den Strich.

    1. Vom DynamicRenderer wird die visuelle Struktur erstellt.
  3. Der Benutzer beendet den Strich.

    1. Der Strich wird von InkPresenter seiner visuellen Struktur hinzugefügt.

    2. Die Striche werden von Media Integration Layer (MIL) statisch gerendert.

    3. Die visuelle Struktur wird vom DynamicRenderer gelöscht.