Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Höhepunkte
- Die klasse DispatcherQueue in der Windows App SDK verwaltet eine priorisierte Warteschlange, in der die Aufgaben für einen Thread serial ausgeführt werden.
- Sie stellt eine Möglichkeit für Hintergrundthreads zum Ausführen von Code im Thread eines DispatcherQueue bereit (z. B. der UI-Thread, in dem Objekte mit Threadaffinität live sind).
- Die Klasse lässt sich präzise in beliebige Nachrichtenschleifen integrieren. Sie unterstützt z. B. das allgemeine Win32-Idiom geschachtelter Nachrichtenschleifen.
- Die AppWindow-Klasse wird in DispatcherQueue integriert– wenn ein DispatcherQueue für einen bestimmten Thread heruntergefahren wird, werden die AppWindow-Instanzen automatisch zerstört.
- Sie bietet eine Möglichkeit zum Registrieren einer Stellvertretung, die aufgerufen wird, wenn ein Timeout abläuft.
- Es stellt Ereignisse bereit, die Komponenten darüber informieren, wann eine Nachrichtenschleife beendet wird, und das Herunterfahren optional aufschieben, bis noch ausstehende Arbeiten abgeschlossen sind. Dadurch wird sichergestellt, dass Komponenten, die die DispatcherQueue verwenden, aber nicht selbst über die Nachrichtenschleife verfügen, beim Beenden der Schleife Bereinigungsarbeiten im Thread ausführen können.
- " DispatcherQueue " ist ein Thread-Singleton (es kann höchstens ein Thread-Singleton vorhanden sein, der auf einem beliebigen Thread ausgeführt wird). Standardmäßig weist ein Thread keine DispatcherQueue auf.
- Ein Threadbesitzer kann einen DispatcherQueueController erstellen, um den DispatcherQueue für den Thread zu initialisieren. Zu diesem Zeitpunkt kann beliebiger Code auf die DispatcherQueue des Threads zugreifen; aber nur der Besitzer des DispatcherQueueController hat Zugriff auf die Methode DispatcherQueueController.ShutdownQueue, die die DispatcherQueue abarbeitet und die Ereignisse ShutdownStarting und ShutdownCompleted auslöst.
- Ein Verantwortlicher für die äußerste Nachrichtenschleife muss eine DispatcherQueue-Instanz erstellen. Nur der Code, der für die Ausführung der äußersten Nachrichtenschleife eines Threads zuständig ist, weiß, wann die Verteilerschleife abgeschlossen ist, was die geeignete Zeit zum Herunterfahren der DispatcherQueue ist. Das bedeutet, dass Komponenten, die auf DispatcherQueue basieren, nicht die DispatcherQueue erstellen müssen, es sei denn, sie besitzen die Nachrichtenschleife des Threads.
Zusammenfassung
Nachdem ein Thread seine Ereignisschleife verlassen hat, muss er seine DispatcherQueue beenden. Dadurch werden die Ereignisse ShutdownStarting und ShutdownCompleted ausgelöst, und alle zuletzt noch ausstehenden eingereihten Elemente werden verarbeitet, bevor das weitere Einreihen deaktiviert wird.
- Um eine DispatcherQueue herunterzufahren, die auf einem dedizierten Thread mit einer DispatcherQueue-eigenen Nachrichtenschleife ausgeführt wird, rufen Sie die Methode DispatcherQueueController.ShutdownQueueAsync auf.
- Rufen Sie für Szenarien, in denen die App eine beliebige Nachrichtenschleife besitzt (z. B. XAML-Inseln), die synchrone DispatcherQueueController.ShutdownQueue-Methode auf. Diese Methode löst Herunterfahren-Ereignisse aus und entwässert die DispatcherQueue synchron im aufrufenden Thread.
Wenn Sie " DispatcherQueueController.ShutdownQueueAsync " oder "DispatcherQueueController.ShutdownQueue" aufrufen, lautet die Reihenfolge der ausgelösten Ereignisse wie folgt:
- ShutdownStarting. Für die Verarbeitung durch Apps vorgesehen.
- FrameworkShutdownStarting. Zur Verarbeitung durch Frameworks vorgesehen.
- FrameworkShutdownCompleted. Zur Verarbeitung durch Frameworks vorgesehen.
- ShutdownCompleted. Zur Verarbeitung durch Apps vorgesehen.
Die Ereignisse werden in Anwendungs-/Framework-Kategorien unterteilt, sodass das geordnete Herunterfahren erreicht werden kann. Das heißt, indem das Herunterfahren der Anwendung explizit vor den Shutdown-Ereignissen des Frameworks ausgelöst wird, besteht keine Gefahr, dass sich eine Framework-Komponente in einem unbrauchbaren Zustand befindet, während die Anwendung heruntergefahren wird.
namespace winrt
{
using namespace Microsoft::UI::Dispatching;
}
// App runs its own custom message loop.
void RunCustomMessageLoop()
{
// Create a DispatcherQueue.
auto dispatcherQueueController{winrt::DispatcherQueueController::CreateOnCurrentThread()};
// Run a custom message loop. Runs until the message loop owner decides to stop.
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!ContentPreTranslateMessage(&msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
// Run down the DispatcherQueue. This single call also runs down the system DispatcherQueue
// if one was created via EnsureSystemDispatcherQueue:
// 1. Raises DispatcherQueue.ShutdownStarting event.
// 2. Drains remaining items in the DispatcherQueue, waits for deferrals.
// 3. Raises DispatcherQueue.FrameworkShutdownStarting event.
// 4. Drains remaining items in the DispatcherQueue, waits for deferrals.
// 5. Disables further enqueuing.
// 6. Raises the DispatcherQueue.FrameworkShutdownCompleted event.
// 7. Raises the DispatcherQueue.ShutdownCompleted event.
dispatcherQueueController.ShutdownQueue();
}
Äußerste und rekursive Nachrichtenschleifen
DispatcherQueue unterstützt benutzerdefinierte Nachrichtenschleifen. Für einfache Apps, die keine Anpassung benötigen, stellen wir jedoch eine Standardimplementierung bereit. Das entlastet Entwickler und trägt dazu bei, ein konsistentes korrektes Verhalten sicherzustellen.
namespace winrt
{
using namespace Microsoft::UI::Dispatching;
}
// Simple app; doesn't need a custom message loop.
void RunMessageLoop()
{
// Create a DispatcherQueue.
auto dispatcherQueueController{winrt::DispatcherQueueController::CreateOnCurrentThread()};
// Runs a message loop until a call to DispatcherQueue.EnqueueEventLoopExit or PostQuitMessage.
dispatcherQueueController.DispatcherQueue().RunEventLoop();
// Run down the DispatcherQueue.
dispatcherQueueController.ShutdownQueue();
}
// May be called while receiving a message.
void RunNestedLoop(winrt::DispatcherQueue dispatcherQueue)
{
// Runs a message loop until a call to DispatcherQueue.EnqueueEventLoopExit or PostQuitMessage.
dispatcherQueue.RunEventLoop();
}
// Called to break out of the message loop, returning from the RunEventLoop call lower down the
// stack.
void EndMessageLoop(winrt::DispatcherQueue dispatcherQueue)
{
// Alternatively, calling Win32's PostQuitMessage has the same effect.
dispatcherQueue.EnqueueEventLoopExit();
}
Verwaltung des System-Dispatchers
Einige Windows App SDK-Komponenten (z. B. MicaController) hängen von Systemkomponenten ab, die wiederum eine System-DispatcherQueue (Windows.System.DispatcherQueue) erfordern, die auf dem Thread ausgeführt wird.
In diesen Fällen ruft die Komponente, die von einer System-DispatcherQueue abhängt, die Methode EnsureSystemDispatcherQueue auf, sodass Ihre App keine System-DispatcherQueue verwalten muss.
Nach dem Aufruf dieser Methode verwaltet die Windows App SDK DispatcherQueue automatisch die Lebensdauer der System-DispatcherQueue, wobei die System-DispatcherQueue zusammen mit der Windows App SDK DispatcherQueue heruntergefahren wird. Komponenten könnten sich sowohl auf das Windows App SDK als auch auf Systemereignisse zum Herunterfahren der DispatcherQueue stützen, um sicherzustellen, dass sie nach dem Beenden der Meldungsschleife ordnungsgemäße Bereinigungsarbeiten durchführen.
namespace winrt
{
using namespace Microsoft::UI::Composition::SystemBackdrops;
using namespace Microsoft::UI::Dispatching;
}
// The Windows App SDK component calls this during its startup.
void MicaControllerInitialize(winrt::DispatcherQueue dispatcherQueue)
{
dispatcherQueue.EnsureSystemDispatcherQueue();
// If the component needs the system DispatcherQueue explicitly, it can now grab it off the thread.
winrt::Windows::System::DispatcherQueue systemDispatcherQueue =
winrt::Windows::System::DispatcherQueue::GetForCurrentThread();
}
void AppInitialize()
{
// App doesn't need to concern itself with the system DispatcherQueue dependency.
auto micaController = winrt::MicaController();
}
AppWindow-Integration
Die AppWindow-Klasse verfügt über Funktionen, die sie in die DispatcherQueue integrieren, sodass AppWindow-Objekte automatisch zerstört werden können, wenn die DispatcherQueueController.ShutdownQueueAsync - oder DispatcherQueueController.ShutdownQueue-Methode aufgerufen wird.
Es gibt auch eine Eigenschaft von AppWindow, mit der Aufrufer die dem AppWindow zugeordnete DispatcherQueue abrufen können, wodurch es an andere Objekte in den Namespaces Composition und Input angeglichen wird.
AppWindow benötigt Ihre explizite Zustimmung, um die DispatcherQueue zu beachten.
namespace winrt
{
using namespace Microsoft::UI::Dispatching;
using namespace Microsoft::UI::Windowing;
}
void Main()
{
// Create a Windows App SDK DispatcherQueue.
auto dispatcherQueueController{winrt::DispatcherQueueController::CreateOnCurrentThread()};
auto appWindow = AppWindow::Create(nullptr, 0, dispatcherQueueController.DispatcherQueue());
// Since we associated the DispatcherQueue above with the AppWindow, we're able to retrieve it
// as a property. If we were to not associate a dispatcher, this property would be null.
ASSERT(appWindow.DispatcherQueue() == dispatcherQueueController.DispatcherQueue());
// Runs a message loop until a call to DispatcherQueue.EnqueueEventLoopExit or PostQuitMessage.
dispatcherQueueController.DispatcherQueue().RunEventLoop();
// Rundown the Windows App SDK DispatcherQueue. While this call is in progress, the AppWindow.Destoyed
// event will be raised since the AppWindow instance is associated with the DispatcherQueue.
dispatcherQueueController.ShutdownQueue();
}
Windows developer