Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Toto téma popisuje, jak používat pracovní fronty ve službě Microsoft Media Foundation.
- používání pracovních front
- Vypnutí pracovních front
- Používání naplánovaných pracovních položek
- Použití periodických callbacků
- související témata
Použití pracovních front
Pracovní fronta je efektivní způsob, jak provádět asynchronní operace v jiném vlákně. Koncepčně vložíte pracovní položky do fronty a fronta má vlákno, které vytahuje každou položku z fronty a odesílá ji. Pracovní položky se implementují jako zpětná volání pomocí rozhraní MMFAsyncCallback.
Media Foundation vytvoří několik standardních pracovních front, označovaných jako pracovní fronty platformy. Aplikace mohou také vytvářet vlastní pracovní fronty, označované jako soukromé pracovní fronty. Seznam pracovních front platformy najdete v tématu Identifikátory pracovní fronty. Chcete-li vytvořit privátní pracovní frontu, zavolejte MFAllocateWorkQueue. Tato funkce navrátí identifikátor pro nově vytvořenou pracovní frontu. Chcete-li vložit položku do fronty, volejte MFPutWorkItem nebo MFPutWorkItemEx. V obou případech musíte zadat rozhraní zpětného volání.
- MFPutWorkItem přijímá ukazatel na rozhraní IMFAsyncCallback a volitelný stavový objekt, který implementuje IUnknown. Jedná se o stejné parametry používané v asynchronních metodách, jak je popsáno v tématu asynchronní metody zpětného volání. Interně tato funkce vytvoří asynchronní objekt výsledku, který je předán metodě Invoke zpětného volání .
- MFPutWorkItemEx přebírá ukazatel na rozhraní MMFAsyncResult. Toto rozhraní představuje asynchronní objekt výsledku. Vytvořte tento objekt voláním MFCreateAsyncResult a zadáním rozhraní zpětného volání a volitelně stavového objektu.
V obou případech vlákno pracovní fronty volá vaši metodu IMFAsyncCallback::Invoke. K provedení pracovní položky použijte metodu Invoke.
Pokud více než jedno vlákno nebo součást sdílí stejnou pracovní frontu, můžete zavolat MFLockWorkQueue, abyste uzamkli pracovní frontu, což brání platformě v jejím uvolnění. Pro každé volání MFAllocateWorkQueue nebo MFLockWorkQueue, musíte jednou zavolat MFUnlockWorkQueue, aby se uvolnila pracovní fronta. Pokud například vytvoříte novou pracovní frontu a jednou ji zamknete, musíte zavolat MFUnlockWorkQueue dvakrát, jednou pro volání MFAllocateWorkQueue a jednou pro volání MFLockWorkQueue.
Následující kód ukazuje, jak vytvořit novou pracovní frontu, vložit pracovní položku do fronty a uvolnit pracovní frontu.
Další informace o pracovních frontách ve Windows 8 najdete v tématu Vylepšení pracovních front a vláken.
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);
}
Tento příklad předpokládá, že pCallback je ukazatel na rozhraní aplikace MMFAsyncCallback. Předpokládá se také, že zpětné volání nastaví hEvent popisovač události. Kód čeká na nastavení této události před voláním MFUnlockWorkQueue.
Vlákna pracovní fronty se vždy vytvářejí v procesu volajícího. V rámci každé pracovní fronty se zpětná volání serializují. Pokud dvakrát voláte MFPutWorkItem se stejnou pracovní frontou, druhé zpětné volání se nevyvolá, dokud se první zpětné volání nevrátí.
Vypnutí pracovních front
Před tím, než zavoláte MFShutdown, uvolněte všechny prostředky, které používají vlákna pracovní fronty. Pokud chcete tento proces synchronizovat, můžete zamknout platformu Media Foundation, která brání funkci MFShutdown, aby zavírala všechna vlákna pracovní fronty. Pokud je MFShutdown volán zatímco je platforma uzamčena, MFShutdown čeká několik stovek milisekund, než se platforma odemkne. Pokud se během této doby neodemkne, MFShutdown zavře vlákna pracovní fronty.
Výchozí implementace MMFAsyncResult automaticky uzamkne platformu Media Foundation při vytvoření výsledného objektu. Uvolnění rozhraní odemkne platformu. Proto téměř nikdy nebudete muset uzamknout platformu přímo. Ale pokud napíšete vlastní implementaci IMFAsyncResult, pak byste měli ručně uzamknout a odemknout platformu. Pokud chcete platformu uzamknout, zavolejte MFLockPlatform. Pokud chcete platformu odemknout, zavolejte MFUnlockPlatform. Pro příklad naleznete vlastní asynchronní výsledkové objekty.
Po volání MFShutdownmusíte zajistit, aby platforma byla odemknutá během 5sekundového časového limitu. Uděláte to tak, že uvolníte všechny ukazatele IMFAsyncResult a zavolejte MFUnlockPlatform, pokud jste platformu uzamkli ručně. Ujistěte se, že uvolníte všechny prostředky, které používají vlákna pracovní fronty, jinak by vaše aplikace mohla mít únik paměti.
Obvykle, pokud vaše aplikace vypne a uvolní všechny objekty Media Foundation před voláním MFShutdown, nemusíte se obávat o uzamčení. Mechanismus uzamčení jednoduše umožňuje, aby pracovní vlákna fronty po volání MFShutdownukončila svůj chod elegantně.
Použití plánovaných pracovních položek
Zpětné volání můžete naplánovat tak, že zavoláte MFScheduleWorkItem nebo MFScheduleWorkItemEx.
- MFScheduleWorkItem vezme ukazatel na zpětné volání, volitelný objekt stavu a interval časového limitu.
- MFScheduleWorkItemEx vezme ukazatel na asynchronní objekt výsledku a hodnotu časového limitu.
Zadejte časový limit jako zápornou hodnotu v milisekundách. Pokud chcete například naplánovat zpětné volání, které se má vyvolat za 5 sekund, použijte hodnotu −5000. Obě funkce vrátí hodnotu MFWORKITEM_KEY, kterou můžete použít ke zrušení zpětného volání předáním do funkce MFCancelWorkItem.
Pracovní položky, které jsou naplánovány, vždy používají pracovní frontu platformy MFASYNC_CALLBACK_QUEUE_TIMER.
Použití pravidelných zpětných volání
Funkce MFAddPeriodicCallback nastaví pravidelné vyvolání callbacku, dokud ho nezrušíte. Interval zpětného volání je pevný; aplikace ho nemohou změnit. Pokud chcete zjistit přesný interval, zavolejte MFGetTimerPeriodicity. Interval je v řádu 10 milisekund, takže tato funkce je určená pro situace, kdy potřebujete častý "tick", například při implementaci prezentačních hodin. Pokud chcete naplánovat operaci tak, aby probíhala méně často, použijte naplánovanou pracovní položku, jak je popsáno výše.
Na rozdíl od ostatních zpětných volání popsaných v tomto tématu nepoužívá pravidelné zpětné volání rozhraní IMFAsyncCallback. Místo toho používá ukazatel funkce. Další informace najdete v tématu MFPERIODICCALLBACK Zpětné volání.
Chcete-li zrušit pravidelné zpětné volání, použijte MFRemovePeriodicCallback.
Periodická zpětná volání využívají pracovní frontu platformy MFASYNC_CALLBACK_QUEUE_TIMER.
Související témata