Dela via


Använda Ramverksarbetsobjekt

Ett arbetsobjekt är en uppgift som en drivrutin utför i en EvtWorkItem-händelseåteranropsfunktion . Dessa funktioner körs asynkront på IRQL = PASSIVE_LEVEL i kontexten för en systemarbetstråd.

Ramverksbaserade drivrutiner använder ofta arbetsobjekt om en EvtInterruptDpc - eller EvtDpcFunc-funktion , som körs på IRQL = DISPATCH_LEVEL, måste utföra ytterligare bearbetning vid IRQL = PASSIVE_LEVEL.

Med andra ord kan en drivrutin använda arbetsobjekt om en funktion som körs på IRQL = DISPATCH_LEVEL måste anropa en funktion som bara kan anropas på IRQL = PASSIVE_LEVEL.

Vanligtvis skapar en drivrutins EvtInterruptDpc - eller EvtDpcFunc-återanropsfunktion ett arbetsobjektobjekt och lägger till det i systemets arbetsobjektkö. Därefter avmarkerar en systemarbetaretråd objektet och anropar arbetsobjektets EvtWorkItem-återanropsfunktion .

Exempeldrivrutiner som använder arbetsobjekt

Exempel på ramverksbaserade drivrutiner som använder arbetsobjekt är 1394, AMCC5933, PCIDRV och Toaster.

Konfigurera ett arbetsobjekt

Om du vill konfigurera ett arbetsobjekt måste drivrutinen:

  1. Skapa arbetsobjektet.

    Drivrutinen anropar WdfWorkItemCreate för att skapa ett arbetsobjekt och identifiera en EvtWorkItem-återanropsfunktion som bearbetar arbetsobjektet.

  2. Lagra information om arbetsobjektet.

    Vanligtvis använder drivrutiner kontextminnet för arbetsobjektobjektet för att lagra information om den uppgift som evtWorkItem-återanropsfunktionen ska utföra. När återanropsfunktionen EvtWorkItem anropas kan den hämta informationen genom att komma åt det här kontextminnet. Information om hur du allokerar och får åtkomst till kontextminne finns i Kontextutrymme för ramverksobjekt.

  3. Lägg till arbetsobjektet i systemets arbetsobjektkö.

    Drivrutinen anropar WdfWorkItemEnqueue, vilket adderar drivrutinens arbetsobjekt till arbetsobjektkön.

När drivrutinen anropar WdfWorkItemCreate måste den ange ett handtag till antingen ett ramverksenhetsobjekt eller ett ramverksköobjekt. När systemet tar bort objektet tas även alla befintliga arbetsobjekt som är associerade med objektet bort. Objektet för arbetsobjektet tas bort och arbetsobjektets associerade återanrop åtgärdas innan det överordnade objektets EvtCleanupCallback-återanrop anropas.

Mer information om rensningsreglerna för en ramverksobjekthierarki finns i Livscykel för ramverksobjekt.

Använda Work-Item-återanropsfunktionen

När arbetsobjektet har lagts till i arbetsobjektkön förblir det kvar i kön tills en systemarbetartråd blir tillgänglig. System worker-tråden tar bort arbetsobjektet från kön och anropar sedan drivrutinens EvtWorkItem-återanropsfunktion och skickar objektet work-item som indata.

Vanligtvis utför återanropsfunktionen EvtWorkItem följande steg:

  1. Hämtar drivrutinslevererad information om arbetsobjektet genom att komma åt kontextminnet för arbetsobjektet.

  2. Utför den uppgift som du har angett. Om det behövs kan återanropsfunktionen anropa WdfWorkItemGetParentObject för att fastställa arbetsobjektets överordnade objekt.

  3. Anropar WdfObjectDelete för att ta bort objektet work-item, eller anger att referensen till arbetsobjektet nu är tillgänglig för återanvändning om drivrutinen ska skickas på nytt.

Uppgiften som varje arbetsobjekts återanropsfunktion utför måste vara relativt kort. Operativsystemet tillhandahåller ett begränsat antal systemarbetstrådar, så att drivrutinen kan hindra systemprestanda om den använder återanropsfunktioner för arbetsobjekt för att utföra tidskrävande uppgifter.

Skapa och ta bort arbetsobjekt

Förare kan använda någon av följande två tekniker för att skapa och ta bort arbetsobjekt.

  • Använd varje arbetsobjekt en gång: skapa arbetsobjektet när du behöver det och ta bort det direkt efter att det har använts.

    Den här tekniken är användbar för förare som kräver sporadisk användning (mindre ofta än en gång per minut) av ett fåtal arbetsobjekt.

    En drivrutins EvtInterruptDpc-återanropsfunktion kan till exempel anropa WdfWorkItemCreate och sedan WdfWorkItemEnqueue, och arbetsobjektets EvtWorkItem-återanropsfunktion kan anropa WdfObjectDelete.

    Om drivrutinen följer det här scenariot, och om dess EvtInterruptDpc-återanropsfunktion tar emot ett STATUS_INSUFFICIENT_RESOURCES returvärde från WdfWorkItemCreate, måste drivrutinen kunna skjuta upp det nödvändiga arbetet tills systemresurser (vanligtvis minne) blir tillgängliga.

  • Skapa ett eller flera arbetsobjekt som drivrutinen begär efter behov.

    Den här tekniken är användbar för drivrutiner som använder arbetsobjekt ofta (oftare än en gång per minut) eller om drivrutinens EvtInterruptDpc-återanropsfunktion inte enkelt kan hantera ett STATUS_INSUFFICIENT_RESOURCES returvärde från WdfWorkItemCreate.

    Systemet allokerar inte en arbetstråd till ett arbetsobjekt förrän drivrutinen anropar WdfWorkItemEnqueue. Även om systemarbetstrådar är en begränsad resurs, förbrukar skapandet av arbetsobjekt samtidigt som en enhet initieras en liten mängd minne, men det påverkar inte i övrigt systemets prestanda.

    Följande steg beskriver ett möjligt scenario:

    1. En drivrutins EvtDriverDeviceAdd-återanropsfunktion anropar WdfWorkItemCreate för att hämta ett arbetsobjekthandtag.
    2. Drivrutinens EvtInterruptDpc-återanropsfunktion skapar en lista över åtgärder som evtWorkItem-återanropsfunktionen måste utföra och anropar sedan WdfWorkItemEnqueue med hjälp av handtaget från steg 1.
    3. Drivrutinens EvtWorkItem-återanropsfunktion utför listan över åtgärder och anger en flagga som anger att återanropsfunktionen har körts.

    Varje gång drivrutinens EvtInterruptDpc-återanropsfunktion anropas måste den därefter avgöra om återanropsfunktionen EvtWorkItem har körts. Om återkallningsfunktionen EvtWorkItem inte har körts, anropar inte funktionen EvtInterruptDpcWdfWorkItemEnqueue, eftersom arbetsobjektet fortfarande är i kö. I det här fallet uppdaterar evtInterruptDpc-återanropsfunktionen endast listan över åtgärder för EvtWorkItem-återanropsfunktionen .

    Varje arbetsobjekt är associerat med en enhet eller en kö. När den associerade enheten eller kön tas bort tar ramverket bort alla associerade arbetsobjekt, så om du använder den här tekniken behöver drivrutinen inte anropa WdfObjectDelete.

Några drivrutiner kan behöva anropa WdfWorkItemFlush för att rensa sina arbetsobjekt från arbetsobjektkön. Ett exempel på användning av WdfWorkItemFlush finns på metodens referenssida.

Om drivrutinen anropar WdfObjectDelete på ett återstående arbetsobjekt beror resultatet på arbetsobjektets tillstånd:

Arbetsobjektstatus Resultat
Skapad men inte köad Arbetsobjekt rensas omedelbart.
Enqueued Anrop till WdfObjectDelete väntar tills arbetsobjektet slutför exekveringen, och därefter rensas arbetsobjektet upp.
Verkställande Om drivrutinen anropar WdfObjectDelete inifrån EvtWorkItem (på samma tråd) returnerar WdfObjectDelete omedelbart. När EvtWorkItem har slutförts rensas arbetsobjektet. Annars väntar WdfObjectDelete på att EvtWorkItem ska slutföras.