Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W tym temacie opisano sposób używania kolejek roboczych w programie Microsoft Media Foundation.
- przy użyciu kolejek roboczych
- zamykanie kolejek roboczych
- Używanie zaplanowanych elementów roboczych
- Korzystanie z okresowych wywołań zwrotnych
- Tematy pokrewne
Korzystanie z kolejek roboczych
Kolejka pracy to wydajny sposób do wykonania operacji asynchronicznych w innym wątku. Koncepcyjnie umieszczasz elementy robocze w kolejce, a kolejka zawiera wątek, który ściąga każdy element z kolejki i wysyła go. Elementy robocze są implementowane jako wywołania zwrotne przy użyciu interfejsu IMFAsyncCallback.
Program Media Foundation tworzy kilka standardowych kolejek roboczych, zwanych kolejkami roboczymi platformy . Aplikacje mogą również tworzyć własne kolejki robocze, nazywane prywatnymi kolejkami roboczymi. Aby uzyskać listę kolejek roboczych platformy, zobacz Identyfikatory kolejek roboczych. Aby utworzyć prywatną kolejkę pracy, wywołaj MFAllocateWorkQueue. Ta funkcja zwraca identyfikator nowej kolejki roboczej. Aby umieścić element w kolejce, wywołaj MFPutWorkItem lub MFPutWorkItemEx. W obu przypadkach należy określić interfejs wywołania zwrotnego.
- MFPutWorkItem przyjmuje wskaźnik do interfejsu IMFAsyncCallback oraz opcjonalny obiekt stanu, który implementuje IUnknown. Są to te same parametry używane w metodach asynchronicznych, jak opisano w temacie Asynchroniczne metody wywołania zwrotnego. Wewnętrznie ta funkcja tworzy obiekt wyniku asynchronicznego, który jest przekazywany do metody wywołania zwrotnego Invoke.
- MFPutWorkItemEx pobiera wskaźnik do interfejsu IMFAsyncResult. Ten interfejs reprezentuje asynchroniczny obiekt wyniku. Utwórz ten obiekt, wywołując MFCreateAsyncResult i określając interfejs wywołania zwrotnego oraz opcjonalnie obiekt stanu.
W obu przypadkach wątek kolejki roboczej wywołuje metodę IMFAsyncCallback::Invoke. Użyj metody Invoke, aby wykonać element roboczy.
Jeśli więcej niż jeden wątek lub składnik współużytkuje tę samą kolejkę roboczą, możesz wywołać MFLockWorkQueue, aby zablokować kolejkę roboczą, co uniemożliwia platformie jej zwolnienie. Dla każdego wywołania MFAllocateWorkQueue lub MFLockWorkQueuenależy wywołać MFUnlockWorkQueue raz, aby zwolnić kolejkę roboczą. Jeśli na przykład utworzysz nową kolejkę pracy, a następnie zablokujesz ją raz, musisz dwukrotnie wywołać MFUnlockWorkQueue, raz przy wywołaniu MFAllocateWorkQueue i raz przy wywołaniu MFLockWorkQueue.
Poniższy kod pokazuje, jak utworzyć nową kolejkę pracy, umieścić element roboczy w kolejce i zwolnić kolejkę pracy.
Aby uzyskać dodatkowe informacje na temat kolejek roboczych w systemie Windows 8, zobacz Ulepszenia kolejek roboczych i wątkowania.
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);
}
W tym przykładzie założono, że pCallback jest wskaźnikiem do interfejsu aplikacji IMFAsyncCallback. Przyjęto również założenie, że wywołanie zwrotne ustawia uchwyt zdarzenia hEvent. Kod czeka na ustawienie tego zdarzenia, zanim wywoła MFUnlockWorkQueue.
Wątki kolejek roboczych są zawsze tworzone w procesie procesu wywołującego. W każdej kolejce pracy wywołania zwrotne są serializowane. Jeśli wywołasz MFPutWorkItem dwa razy z tą samą kolejką pracy, drugie wywołanie zwrotne nie jest realizowane, dopóki pierwsze wywołanie zwrotne nie zostanie wykonane.
Zamykanie kolejek roboczych
Przed wywołaniem MFShutdown , zwolnij wszystkie zasoby używane przez wątki kolejki roboczej. Aby zsynchronizować ten proces, można zablokować platformę Media Foundation, która uniemożliwia funkcji MFShutdown zamykanie wszystkich wątków kolejki roboczej. Jeśli MFShutdown jest wywoływana, gdy platforma jest zablokowana, MFShutdown czeka kilkaset milisekund na odblokowanie platformy. Jeśli nie zostanie odblokowany w tym czasie, MFShutdown zamyka wątki kolejki roboczej.
Domyślna implementacja IMFAsyncResult automatycznie blokuje platformę Media Foundation po utworzeniu obiektu wyniku. Odblokowanie interfejsu odblokowuje platformę. W związku z tym prawie nigdy nie trzeba bezpośrednio blokować platformy. Jeśli jednak napiszesz własną niestandardową implementację IMFAsyncResult, powinieneś ręcznie zablokować, a następnie odblokować platformę. Aby zablokować platformę, wywołaj MFLockPlatform. Aby odblokować platformę, wywołaj MFUnlockPlatform. Aby zapoznać się z przykładem, zobacz niestandardowe asynchroniczne obiekty wynikowe.
Po wywołaniu MFShutdown należy upewnić się, że platforma jest odblokowana w ciągu 5-sekundowego limitu czasu. Zrób to, zwalniając wszystkie wskaźniki IMFAsyncResult i wywołując MFUnlockPlatform, jeśli zablokowałeś platformę ręcznie. Pamiętaj, aby zwolnić wszystkie zasoby, które są używane przez wątki kolejek roboczych, lub aplikacja może dochodzić do wycieku pamięci.
Zazwyczaj jeśli aplikacja zostanie zamknięta i zwolni każdy obiekt programu Media Foundation przed wywołaniem MFShutdown, nie musisz martwić się o blokowanie. Mechanizm blokowania pozwala po prostu wątkom kolejki roboczej bezproblemowo zakończyć pracę po wywołaniu MFShutdown .
Używanie zaplanowanych elementów roboczych
Można zaplanować wykonanie wywołania zwrotnego po określonym czasie, korzystając z MFScheduleWorkItem lub MFScheduleWorkItemEx.
- MFScheduleWorkItem obsługuje wskaźnik do wywołania zwrotnego, opcjonalny obiekt stanu i przedział czasowy limitu.
- MFScheduleWorkItemEx zawiera wskaźnik do obiektu wyniku asynchronicznego oraz wartość limitu czasu.
Określ limit czasu jako wartość ujemną w milisekundach. Aby na przykład zaplanować wywołanie zwrotne w ciągu 5 sekund, użyj wartości −5000. Obie funkcje zwracają wartość MFWORKITEM_KEY, której można użyć do anulowania wywołania zwrotnego, przekazując ją do funkcji MFCancelWorkItem.
Zaplanowane elementy robocze zawsze używają kolejki roboczej platformy MFASYNC_CALLBACK_QUEUE_TIMER.
Używanie okresowych wywołań zwrotnych
Funkcja MFAddPeriodicCallback planuje wywołanie zwrotne, które ma być wywoływane okresowo, aż je anulujesz. Interwał wywołania zwrotnego jest stały; aplikacje nie mogą go zmieniać. Aby sprawdzić dokładny interwał, wywołaj metodę MFGetTimerPeriodicity. Interwał wynosi około 10 milisekund, więc ta funkcja jest przeznaczona do sytuacji, w których potrzebujesz częstego "znacznika", takiego jak ustawienie zegara prezentacji. Jeśli chcesz zaplanować operację, która ma wystąpić rzadziej, użyj zaplanowanego elementu roboczego, zgodnie z wcześniejszym opisem.
W przeciwieństwie do innych wywołań zwrotnych opisanych w tym temacie, okresowe wywołanie zwrotne nie używa interfejsu IMFAsyncCallback. Zamiast tego używa wskaźnika funkcji. Aby uzyskać więcej informacji, zobacz MFPERIODICCALLBACK Callback.
Aby anulować okresowe wywołanie zwrotne, wywołaj MFRemovePeriodicCallback.
Wywołania zwrotne okresowe używają kolejki roboczej platformy MFASYNC_CALLBACK_QUEUE_TIMER.
Tematy pokrewne