Verwenden von Arbeitswarteschlangen
In diesem Thema wird beschrieben, wie Arbeitswarteschlangen in Microsoft Media Foundation verwendet werden.
- Verwenden von Arbeitswarteschlangen
- Herunterfahren von Arbeitswarteschlangen
- Verwenden von geplanten Arbeitselementen
- Verwenden periodischer Rückrufe
- Zugehörige Themen
Verwenden von Arbeitswarteschlangen
Eine Arbeitswarteschlange ist eine effiziente Möglichkeit, asynchrone Vorgänge für einen anderen Thread auszuführen. Konzeptionell legen Sie Arbeitselemente in die Warteschlange ein, und die Warteschlange verfügt über einen Thread, der jedes Element aus der Warteschlange abruft und verteilt. Arbeitselemente werden als Rückrufe implementiert, indem die INTERFACESAsyncCallback-Schnittstelle verwendet wird.
Media Foundation erstellt mehrere Standardarbeitswarteschlangen, die als Plattformarbeitswarteschlangen bezeichnet werden. Anwendungen können auch eigene Arbeitswarteschlangen erstellen, die als private Arbeitswarteschlangen bezeichnet werden. Eine Liste der Plattformarbeitswarteschlangen finden Sie unter Arbeitswarteschlangenbezeichner. Um eine private Arbeitswarteschlange zu erstellen, rufen Sie MFAllocateWorkQueueauf. Diese Funktion gibt einen Bezeichner für die neue Arbeitswarteschlange zurück. Um ein Element in die Warteschlange zu stellen, rufen Sie MFPutWorkItem oder MFPutWorkItemExauf. In beiden Fällen müssen Sie eine Rückrufschnittstelle angeben.
- MFPutWorkItem verwendet einen Zeiger auf die SCHNITTSTELLE "AWAITAsyncCallback" sowie ein optionales Zustandsobjekt, das IUnknown implementiert. Dies sind die gleichen Parameter, die in asynchronen Methoden verwendet werden, wie im Thema Asynchrone Rückrufmethodenbeschrieben. Intern erstellt diese Funktion ein asynchrones Ergebnisobjekt, das an die Invoke-Methode des Rückrufs übergeben wird.
- MFPutWorkItemEx verwendet einen Zeiger auf die SCHNITTSTELLE "POINTERAsyncResult". Diese Schnittstelle stellt ein asynchrones Ergebnisobjekt dar. Erstellen Sie dieses Objekt, indem Sie MFCreateAsyncResult aufrufen und Ihre Rückrufschnittstelle und optional ein Zustandsobjekt angeben.
In beiden Fällen ruft der Arbeitswarteschlangenthread ihre METHODE "AWAITAsyncCallback::Invoke" auf. Verwenden Sie die Invoke-Methode, um das Arbeitselement auszuführen.
Wenn mehrere Threads oder Komponenten dieselbe Arbeitswarteschlange gemeinsam nutzen, können Sie MFLockWorkQueue aufrufen, um die Arbeitswarteschlange zu sperren, wodurch verhindert wird, dass die Plattform sie freigibt. Für jeden Aufruf von MFAllocateWorkQueue oder MFLockWorkQueue müssen Sie MFUnlockWorkQueue einmal aufrufen, um die Arbeitswarteschlange freizugeben. Wenn Sie beispielsweise eine neue Arbeitswarteschlange erstellen und diese dann einmal sperren, müssen Sie MFUnlockWorkQueue zweimal aufrufen, einmal für den Aufruf von MFAllocateWorkQueue und einmal für den Aufruf von MFLockWorkQueue.
Der folgende Code zeigt, wie Sie eine neue Arbeitswarteschlange erstellen, ein Arbeitselement in die Warteschlange stellen und die Arbeitswarteschlange freigeben.
Weitere Informationen zu Arbeitswarteschlangen in Windows 8 finden Sie unter Verbesserungen der Arbeitswarteschlange und des Threadings.
DWORD idWorkQueue = 0;
HRESULT hr = S_OK;
// Create a new work queue.
hr = MFAllocateWorkQueue(&idWorkQueue);
// Put an item on the queue.
if (SUCCEEDED(hr))
{
hr = MFPutWorkItem(idWorkQueue, pCallback, NULL);
}
// Wait for the callback to be invoked.
if (SUCCEEDED(hr))
{
WaitForSingleObject(hEvent, INFINITE);
}
// Release the work queue.
if (SUCCEEDED(hr))
{
hr = MFUnlockWorkQueue(idWorkQueue);
}
In diesem Beispiel wird davon ausgegangen, dass pCallback ein Zeiger auf die SCHNITTSTELLE "POINTERAsyncCallback" der Anwendung ist. Außerdem wird davon ausgegangen, dass der Rückruf das hEvent-Ereignishandle festlegt. Der Code wartet, bis dieses Ereignis festgelegt wird, bevor MFUnlockWorkQueueaufgerufen wird.
Arbeitswarteschlangenthreads werden immer im Prozess des Aufrufers erstellt. Innerhalb jeder Arbeitswarteschlange werden die Rückrufe serialisiert. Wenn Sie MFPutWorkItem zweimal mit derselben Arbeitswarteschlange aufrufen, wird der zweite Rückruf erst aufgerufen, nachdem der erste Rückruf zurückgegeben wurde.
Herunterfahren von Arbeitswarteschlangen
Geben Sie vor dem Aufrufen von MFShutdownalle Ressourcen frei, die von Arbeitswarteschlangenthreads verwendet werden. Um diesen Prozess zu synchronisieren, können Sie die Media Foundation Plattform sperren, wodurch verhindert wird, dass die MFShutdown-Funktion Arbeitswarteschlangenthreads schließt. Wenn MFShutdown aufgerufen wird, während die Plattform gesperrt ist, wartet MFShutdown einige hundert Millisekunden, bis die Plattform entsperrt wurde. Wenn sie innerhalb dieser Zeit nicht entsperrt wird, schließt MFShutdown die Arbeitswarteschlangenthreads.
Die Standardimplementierung von AWAITAsyncResult sperrt automatisch die Media Foundation Plattform, wenn das Ergebnisobjekt erstellt wird. Durch freigeben der Schnittstelle wird die Plattform entsperrt. Daher müssen Sie die Plattform fast nie direkt sperren. Wenn Sie jedoch Ihre eigene benutzerdefinierte Implementierung von AWAITAsyncResult schreiben, sollten Sie die Plattform manuell sperren und entsperren. Um die Plattform zu sperren, rufen Sie MFLockPlatformauf. Um die Plattform zu entsperren, rufen Sie MFUnlockPlatformauf. Ein Beispiel finden Sie unter Benutzerdefinierte asynchrone Ergebnisobjekte.
Nachdem Sie MFShutdownaufgerufen haben, müssen Sie sicherstellen, dass die Plattform innerhalb des 5-Sekunden-Time out-Zeitraums entsperrt wird. Geben Sie hierzu alle POINTERAsyncResult-Zeiger frei, und rufen Sie MFUnlockPlatform auf, wenn Sie die Plattform manuell gesperrt haben. Stellen Sie sicher, dass Sie alle Ressourcen freigeben, die von Arbeitswarteschlangenthreads verwendet werden, andernfalls kann Ihre Anwendung Arbeitsspeicherverlust aufweisen.
Wenn Ihre Anwendung jedes Media Foundation Objekt herunterfährt und freigibt, bevor MFShutdownaufgerufen wird, müssen Sie sich in der Regel keine Gedanken über sperren machen. Mit dem Sperrmechanismus können Arbeitswarteschlangenthreads einfach ordnungsgemäß beendet werden, nachdem Sie MFShutdown aufgerufen haben.
Verwenden von geplanten Arbeitselementen
Sie können einen Rückruf nach einem festgelegten Zeitraum planen, indem Sie MFScheduleWorkItem oder MFScheduleWorkItemExaufrufen.
- MFScheduleWorkItem verwendet einen Zeiger auf Ihren Rückruf, ein optionales Zustandsobjekt und ein Time out-Intervall.
- MFScheduleWorkItemEx verwendet einen Zeiger auf ein asynchrones Ergebnisobjekt und einen Time out-Wert.
Geben Sie das Time out als negativen Wert in Millisekunden an. Verwenden Sie beispielsweise den Wert "−5000", um einen Rückruf in 5 Sekunden zu planen. Beide Funktionen geben einen MFWORKITEM _ KEY-Wert zurück, den Sie verwenden können, um den Rückruf abzubrechen, indem Sie ihn an die MFCancelWorkItem-Funktion übergeben.
Geplante Arbeitselemente verwenden immer die _ MFASYNC CALLBACK _ QUEUE _ TIMER-Plattformarbeitswarteschlange.
Verwenden periodischer Rückrufe
Die MFAddPeriodicCallback-Funktion plant, dass ein Rückruf regelmäßig aufgerufen wird, bis Sie ihn abbrechen. Das Rückrufintervall ist festgelegt. -Anwendungen können sie nicht ändern. Rufen Sie MFGetTimerPericityauf, um das genaue Intervall zu ermitteln. Das Intervall liegt in der Größenordnung von 10 Millisekunden, sodass diese Funktion für Situationen vorgesehen ist, in denen Sie häufig ein "Tick" benötigen, z. B. die Implementierung einer Präsentationsuhr. Wenn Sie planen möchten, dass ein Vorgang weniger häufig auftritt, verwenden Sie ein geplantes Arbeitselement, wie zuvor beschrieben.
Im Gegensatz zu den anderen rückrufs, die in diesem Thema beschrieben werden, verwendet der regelmäßige Rückruf nicht die INTERFACESAsyncCallback-Schnittstelle. Stattdessen wird ein Funktionszeiger verwendet. Weitere Informationen finden Sie unter MFPERIODICCALLBACK Callback.
Um den periodischen Rückruf abzubrechen, rufen Sie MFRemovePeriodicCallback auf.
Regelmäßige Rückrufe verwenden die Arbeitswarteschlange der MFASYNC _ CALLBACK _ QUEUE _ TIMER-Plattform.