WdfWorkItemEnqueue-Funktion (wdfworkitem.h)
[Gilt für KMDF und UMDF]
Die WdfWorkItemEnqueue--Methode fügt der Arbeitsaufgabenwarteschlange des Systems ein angegebenes Framework-Arbeitselementobjekt hinzu.
Syntax
void WdfWorkItemEnqueue(
[in] WDFWORKITEM WorkItem
);
Parameter
[in] WorkItem
Ein Handle für ein Framework-Arbeitselementobjekt, das aus einem vorherigen Aufruf von WdfWorkItemCreateabgerufen wird.
Rückgabewert
Nichts
Bemerkungen
Wenn der Treiber ein ungültiges Objekthandle bereitstellt, tritt eine Fehlerüberprüfung auf.
Nachdem der Treiber WdfWorkItemCreate aufgerufen hat, um eine Arbeitsaufgabe zu erstellen, muss der Treiber WdfWorkItemEnqueue- aufrufen, um die Arbeitsaufgabe zur Arbeitsaufgabenwarteschlange des Systems hinzuzufügen. Ein Systemarbeitsthread entfernt anschließend die Arbeitsaufgabe aus der Warteschlange und ruft die EvtWorkItem Rückruffunktion der Arbeitsaufgabe auf. Das System entfernt die Arbeitsaufgaben in der Reihenfolge, in der sie der Warteschlange hinzugefügt wurden.
Bevor Treiber WdfWorkItemEnqueueaufrufen, verwenden sie in der Regel den Kontextspeicher des Arbeitselements, um Informationen zur Arbeitsaufgabe zu speichern. Die EvtWorkItem Rückruffunktion verwendet diese Informationen, um den auszuführenden Vorgang zu bestimmen.
Wenn ihr Treiber seine Arbeitsaufgabenobjekte wiederverwendet, kann der Treiber für Versionen 1.7 und höher WdfWorkItemEnqueue für dieselbe Arbeitsaufgabe erneut aufrufen, bevor ein Systemarbeitsthread die Arbeitsaufgabe aufgehoben und anschließend die EvtWorkItem-Funktion Rückruffunktion des Treibers aufgerufen hat. KMDF fügt die Arbeitsaufgabe jedoch nicht zur Warteschlange hinzu, wenn sie bereits vorhanden ist. Daher muss Ihre EvtWorkItem- Rückruffunktion alle in die Warteschlange eingereihten Aufgaben jedes Mal verarbeiten, wenn sie aufgerufen wird.
Ihr Treiber kann auch WdfWorkItemEnqueue- aufrufen, während eine EvtWorkItem- Rückruffunktion ausgeführt wird, um eine andere Arbeitsaufgabe in die Warteschlange zu stellen. Der EvtWorkItem- Rückruf der zweiten Arbeitsaufgabe kann sogar ausgeführt werden, bevor das erste abgeschlossen wird.
Wenn Ihr Treiber seine Arbeitsaufgabenobjekte in Versionen von KMDF vor Version 1.7 wiederverwendet, darf er nicht WdfWorkItemEnqueue erneut für dieselbe Arbeitsaufgabe aufrufen, bis ein Systemarbeitsthread die Arbeitsaufgabe aufgehoben und die EvtWorkItem Rückruffunktion aufgerufen hat.
Weitere Informationen zu Arbeitsaufgaben finden Sie unter Using Framework Work Items.
Beispiele
Dieser Abschnitt enthält zwei Beispiele. Das erste Beispiel zeigt, wie Arbeitselemente zu einer Warteschlange für KMDF-Versionen 1.7 und höher hinzugefügt werden. Das zweite Beispiel zeigt, wie Arbeitselemente einer Warteschlange für KMDF-Versionen vor Version 1.7 hinzugefügt werden.
Beispiel 1: KMDF-Versionen 1.7 und höher
Im folgenden Codebeispiel wird eine lokale Routine aufgerufen, die einen Zeiger auf den Kontextspeicher eines Arbeitselementobjekts zurückgibt. Im Beispiel werden Informationen im Kontextspeicher des Objekts festgelegt und dann WdfWorkItemEnqueueaufgerufen. Die EvtWorkItem Rückruffunktion des Treibers ruft später die Informationen aus dem Arbeitselementobjekt ab.
PMY_CONTEXT_TYPE context;
context = GetWorkItemContext(hWorkItem);
context->FdoData = FdoData;
context->Argument1 = Context1;
context->Argument2 = Context2;
WdfWorkItemEnqueue(hWorkItem);
Die EvtWorkItem Rückruffunktion des Treibers enthält den folgenden Code.
MyWorkItemCallback (
IN WDFWORKITEM hWorkItem
)
{
PMY_CONTEXT_TYPE context;
context = GetWorkItemContext(hWorkItem);
//
// Do work here.
//
...
//
return;
}
Beispiel 2: KMDF-Versionen vor 1.7
Im folgenden Codebeispiel wird eine lokale Routine aufgerufen, die einen Zeiger auf den Kontextspeicher eines Arbeitselementobjekts zurückgibt. Im Beispiel werden Informationen im Kontextspeicher des Objekts festgelegt, eine Zustandsvariable auf "beschäftigt" festgelegt und dann WdfWorkItemEnqueueaufgerufen. Die EvtWorkItem Rückruffunktion des Treibers ruft später die Informationen aus dem Arbeitselementobjekt ab.
typedef enum _WORKITEM_STATE {
WORKITEM_STATE_FREE =0,
WORKITEM_STATE_BUSY = 1
} WORKITEM_STATE;
...
PMY_CONTEXT_TYPE context;
context = GetWorkItemContext(hWorkItem);
context->FdoData = FdoData;
context->Argument1 = Context1;
context->Argument2 = Context2;
if (InterlockedCompareExchange(
(PLONG)&context->WorkItemState,
WORKITEM_STATE_BUSY,
WORKITEM_STATE_FREE
) == WORKITEM_STATE_FREE) {
WdfWorkItemEnqueue(hWorkItem);
}
Die EvtWorkItem Rückruffunktion des Treibers enthält den folgenden Code. Unmittelbar vor dem -Anweisung zurückgeben, legt der Code die Statusvariable des Arbeitselementobjekts auf "frei" fest, sodass der Treiber das Objekt erneut in die Warteschlange stellen kann.
MyWorkItemCallback (
IN WDFWORKITEM hWorkItem
)
{
PMY_CONTEXT_TYPE context;
LONG result;
context = GetWorkItemContext(hWorkItem);
//
// Do work here.
//
...
//
// Reset object state.
//
result = InterlockedExchange(
(PLONG)&context->WorkItemState,
WORKITEM_STATE_FREE
);
ASSERT(result == WORKITEM_STATE_BUSY);
return;
}
Anforderungen
Anforderung | Wert |
---|---|
Zielplattform- | Universal |
Minimale KMDF-Version | 1.0 |
Mindest-UMDF-Version | 2.0 |
Header- | wdfworkitem.h (include Wdf.h) |
Library | Wdf01000.sys (KMDF); WUDFx02000.dll (UMDF) |
IRQL- | <= DISPATCH_LEVEL |
DDI-Complianceregeln | DeferredRequestCompleted(kmdf), DriverCreate(kmdf), KmdfIrql(kmdf), Kmdf, KmdfIrqlExplicit(kmdf), RequestCompleted(kmdf), RequestCompletedLocal(kmdf) |