Asynchrones Modell

Die meisten Vorgänge in der Windows-Webdienst-API können synchron oder asynchron ausgeführt werden. Um eine Funktion synchron aufzurufen, übergeben Sie einen NULL-Wert für die WS_ASYNC_CONTEXT-Struktur . Um anzugeben, dass eine Funktion asynchron ausgeführt werden kann, übergeben Sie eine nicht NULL-WS_ASYNC_CONTEXT an die Funktion.

Beim asynchronen Aufruf kann eine Funktion dennoch synchron oder asynchron abgeschlossen werden. Wenn die Funktion synchron abgeschlossen wird, gibt sie einen Wert zurück, der den endgültigen Erfolg oder Den endgültigen Fehler angibt, und dieser Wert ist immer etwas anderes als WS_S_ASYNC (siehe Rückgabewerte für Windows-Webdienste). Ein Rückgabewert von WS_S_ASYNC gibt jedoch an, dass die Funktion asynchron abgeschlossen wird. Wenn die Funktion asynchron abgeschlossen wird, wird ein Rückruf aufgerufen, um den Abschluss des Vorgangs zu signalisieren. Dieser Rückruf gibt den endgültigen Erfolgs- oder Fehlerwert an. Der Rückruf wird nicht aufgerufen, wenn der Vorgang synchron abgeschlossen wird.

Um einen asynchronen Kontext zu erstellen, initialisieren Sie die Felder callback und callbackState der WS_ASYNC_CONTEXT-Struktur . Das Feld callbackState wird verwendet, um einen Zeiger auf benutzerdefinierte Daten anzugeben, der an die WS_ASYNC_CALLBACK-Funktion übergeben wird.

Das folgende Beispiel zeigt das asynchrone Aufrufen einer Funktion durch Übergeben eines Zeigers an eine WS_ASYNC_CONTEXT Struktur, die den Rückruf und einen Zeiger auf die Zustandsdaten enthält.

HRESULT ExampleAsyncFunction(WS_ASYNC_CONTEXT* asyncContext);
void ExampleAsyncFunction()
{
    // Set up the WS_ASYNC_CONTEXT structure.
    MyState* myState = ...;  \\ Declare a pointer to user-defined data.
    WS_ASYNC_CONTEXT asyncContext;
    asyncContext.callback = MyCallback;  \\ Set the callback.
    asyncContext.callbackState = myState; \\ Set the pointer to the user-defined data.

    // Start the asynchronous operation
    HRESULT hr = SomeFunction(&asyncContext);

    if (hr == WS_S_ASYNC)
    {
        // The operation is completing asynchronously.  The callback is called 
        // when the operation is complete.
    }
    else
    {
        // The operation completed synchronously.  The callback is not called.
    }
}
void CALLBACK MyCallback(HRESULT hr, WS_CALLBACK_MODEL callbackModel, void* callbackState)
{
    MyState* myState = (MyState*)callbackState;

    // The operation completed asynchronously.
}

Die WS_ASYNC_CONTEXT Struktur wird von der asynchronen Funktion nur für die Dauer des Funktionsaufrufs (nicht für die Dauer des asynchronen Vorgangs) verwendet, sodass Sie sie sicher im Stapel deklarieren können.

Wenn andere Parameter neben der WS_ASYNC_CONTEXT-Struktur als Zeiger an eine asynchrone Funktion übergeben werden und die Funktion asynchron abgeschlossen wird, liegt es in der Verantwortung des Aufrufers, die Werte, auf die von diesen Parametern verwiesen wird, am Leben zu halten (nicht freigegeben), bis der asynchrone Rückruf aufgerufen wird.

Es gibt Einschränkungen hinsichtlich der Vorgänge, die ein Rückruf ausführen kann. Weitere Informationen zu möglichen Vorgängen finden Sie im WS_CALLBACK_MODEL.

Wenn Sie eine asynchrone Funktion implementieren, rufen Sie den Rückruf nicht für denselben Thread auf, der die asynchrone Funktion aufgerufen hat, bevor die asynchrone Funktion an den Aufrufer zurückgegeben wurde, da dadurch das asynchrone Modell unterbrochen wird.

Wenn Sie eine Funktion implementieren, die eine Reihe asynchroner Vorgänge ausführen muss, sollten Sie die Hilfsfunktion WsAsyncExecute verwenden.

Das asynchrone Funktionsbeispiel zeigt, wie Funktionen implementiert und genutzt werden, die dem asynchronen Modell folgen.

Beim Starten eines asynchronen E/A-Vorgangs werden Systemressourcen beansprucht. Wenn genügend E/A-Vorgänge gestartet werden, kann das System nicht mehr reagieren. Um dies zu verhindern, muss eine Anwendung die Anzahl der gestarteten asynchronen Vorgänge begrenzen.

Das asynchrone Modell verwendet die folgenden API-Elemente.

Rückruf BESCHREIBUNG
WS_ASYNC_CALLBACK Der Rückruffunktionsparameter, der mit dem asynchronen Modell verwendet wird.
WS_ASYNC_FUNCTION Wird mit WsAsyncExecute verwendet, um die nächste Funktion anzugeben, die in einer Reihe asynchroner Vorgänge aufgerufen werden soll.

 

Enumeration Beschreibung
WS_CALLBACK_MODEL Gibt das Threadingverhalten eines Rückrufs an (z. B. eine WS_ASYNC_CALLBACK).

 

Funktion BESCHREIBUNG
WsAsyncExecute Ruft einen benutzerdefinierten Rückruf auf, der einen asynchronen Vorgang initiieren und eine Funktion angibt, die aufgerufen werden soll, wenn der asynchrone Vorgang abgeschlossen wurde.

 

Struktur BESCHREIBUNG
WS_ASYNC_CONTEXT Gibt den asynchronen Rückruf und einen Zeiger auf benutzerdefinierte Daten an, die an den asynchronen Rückruf übergeben werden.
WS_ASYNC_OPERATION Wird mit WsAsyncExecute verwendet, um die nächste Funktion anzugeben, die in einer Reihe asynchroner Vorgänge aufgerufen werden soll.
WS_ASYNC_STATE Wird von WsAsyncExecute verwendet, um den Zustand eines asynchronen Vorgangs zu verwalten.

 

Asynchrones Funktionsbeispiel

WS_ASYNC_CALLBACK

WS_ASYNC_CONTEXT

WS_CALLBACK_MODEL

WsAsyncExecute