Freigeben über


Asynchron

Das asynchrone Beispiel veranschaulicht, wie ein Client auf einen Dienstvorgang asynchron zugreifen und wie ein Dienst seine Vorgänge asynchron implementieren kann. Dieses Beispiel basiert auf dem Beispiel 'Erste Schritte', das einen Rechnerdienst implementiert. Die Verwendung von synchronen oder asynchronen Aufrufen ist eine lokale Entscheidung und hat keinen Einfluss auf gesendete Nachrichten. Obwohl der Dienst einige synchrone Operationen implementiert, kann der Client asynchron auf die Dienstvorgänge zugreifen. Auch wenn der Client den Dienst synchron aufruft, kann der Dienst einige Vorgänge asynchron implementieren.

ms751505.note(de-de,VS.100).gifHinweis:
Die Setupprozedur und die Erstellungsanweisungen für dieses Beispiel befinden sich am Ende dieses Abschnitts.

In diesem Beispiel ist der Client eine Konsolenanwendung (.exe), und der Dienst ist in einer Konsolenanwendung (*.exe) selbst gehostet.

Der Dienst implementiert die ICalculator-Schnittstelle. Der Client kann die Vorgänge asynchron auf dieser Schnittstelle aufrufen, wodurch Vorgänge wie Add nun ein BeginAdd und ein EndAdd besitzen.

ms751505.note(de-de,VS.100).gifHinweis:
Weitere Details zum asynchronen Muster finden Sie in der .NET Framework-Dokumentation.

Der Client hat Code generiert, in dem diese asynchronen Vorgänge unterstützt werden. Der Client wurde erstellt, indem das Tool ServiceModel Metadata Utility-Tool (Svcutil.exe) mit der /a (async)-Befehlsoption wie folgt ausgeführt wurde:

svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples https://localhost:8000/servicemodelsamples/service/mex /a /tcv:Version35

Die asynchrone Clientversion des Dienstvertrags für den Vorgang Add entspricht dem nachstehenden Codebeispiel.

[System.ServiceModel.ServiceContractAttribute(Namespace=
                   "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [System.ServiceModel.OperationContractAttribute(
       AsyncPattern=true)]
    System.IAsyncResult BeginAdd(double n1, double n2, 
                   System.AsyncCallback callback, object asyncState);
    double EndAdd(System.IAsyncResult result);
    
    ...
}

Wenn die Option /tcv:Version35 zusammen mit der Option /async angegeben ist, implementiert der generierte Clienttyp das ereignisbasierte asynchrone Muster zum Aufrufen des Diensts. Informationen finden Sie unter Übersicht über ereignisbasierte asynchrone Muster (möglicherweise nur in englischer Sprache). Zum asynchronen Aufrufen eines Dienstvorgangs fügt die Anwendung einen Ereignishandler zum Ereignis [Operation]Completed auf dem Client hinzu und ruft anschließend die Methode [Operation]Async auf (z. B. AddAsync, wie in folgendem Beispielcode dargestellt).

// Create a client.
CalculatorClient client = new CalculatorClient();

// BeginAdd.
double value1 = 100.00D;
double value2 = 15.99D;

client.AddCompleted += new EventHandler<AddCompletedEventArgs>(AddCallback);
client.AddAsync(value1, value2);

In dem Beispiel startet der Client zwei Vorgänge asynchron: Add und Subtract.

Wenn die Rückruffunktion ausgeführt wird, ruft der Client die Eigenschaft Result für den Eingabeparameter [Operation]CompletedEventArgs auf, um das Ergebnis abzurufen.

static void AddCallback(object sender, AddCompletedEventArgs e)
{
 Console.WriteLine("Add Result: {0}", e.Result);
}

Das gesamte asynchrone Verhalten findet lokal auf dem Client statt und hat keine Bedeutung für die Art und Weise, wie Nachrichten vom Client gesendet oder vom Dienst verarbeitet werden. Der typische Grund für die Verwendung dieses Musters in einer Anwendung mit einer Benutzeroberfläche (UI) besteht darin, den UI-Thread für die Aktualisierung des Bildschirms freizuhalten. Dieses Muster kann auch angewendet werden, wenn ein Dienst als Client fungiert und der Nachrichtenverarbeitungsthread keine anderen Dienste aufrufen soll. Der nächste Abschnitt veranschaulicht, wie Dienstvorgänge asynchron gemacht werden.

Der Dienst implementiert die ICalculator-Schnittstelle, wie im folgenden Code veranschaulicht.

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [OperationContract]
    double Add(double n1, double n2);
    
    [OperationContract]
    double Subtract(double n1, double n2);
    
    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginMultiply(double n1, double n2,
        AsyncCallback callback, object state);
    double EndMultiply(IAsyncResult ar);

    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginDivide(double n1, double n2, 
        AsyncCallback callback, object state);
    double EndDivide(IAsyncResult ar); 
}

Die ersten beiden Vorgänge des Vertrags werden von der Windows Communication Foundation (WCF)-Laufzeit synchron aufgerufen. Die letzten beiden Vorgangspaare werden zum asynchronen Aufrufen des Diensts verwendet. Im folgenden Beispiel wird die AsyncPattern-Eigenschaft auf true festgelegt. Diese Eigenschaftseinstellung in Verbindung mit der Implementierung des asynchronen .NET Framework-Musters weist die Laufzeit an, den Vorgang asynchron aufzurufen.

Der Grund für die Verwendung dieses Musters in einer Dienstimplementierung ist normalerweise das Freihalten von Nachrichtenverarbeitungsthreads während der Durchführung zeitintensiver Eingabe- und Ausgabevorgänge wie Zugriff auf die Festplatte oder eine Datenbank oder das Aufrufen eines anderen Diensts. In diesem Beispiel wird veranschaulicht, wie Dateieingabe- und -ausgabevorgänge mit einer Implementierung von IAsyncResult eingebunden werden. Die Basisklasse für die Implementierung der Klasse MathAsyncResult kann erneut verwendet werden, um eigene Implementierungen von IAsyncResult zu erstellen.

ms751505.note(de-de,VS.100).gifHinweis:
In diesem Beispiel werden PerCall und Multiple verwendet, um das Bestellungsverhalten zu verhindern, das bei einer sitzungsbasierten Bindung der Fall ist. "wsHttpBinding" verwendet eine Sitzung, um Sicherheitskontext standardmäßig einzurichten. Davon wird die asynchrone Nachrichtenverarbeitung auf dem Client oder Dienst nicht betroffen, die zeitliche Steuerung von Antworten wird jedoch hervorgehoben, und der Client kann gleichzeitige (statt serieller) Rückrufe überwachen.

Wenn Sie das Beispiel ausführen, werden die Anforderungen und Antworten des Vorgangs im Konsolenfenster des Clients angezeigt. Die Anforderungen Add und Subtract werden nicht blockiert, da sie asynchron aufgerufen werden. Anschließend werden die Vorgänge Multiply und Divide blockiert, und ihre Ergebnisse werden zum gleichen Zeitpunkt angezeigt, an dem die Anforderungen gesendet werden. Schließlich werden die Ergebnisse der Vorgänge Add und Subtract angezeigt, wenn diese Ergebnisse zurück an den Client gesendet werden. sleep wird in der Implementierung des Diensts von Add und Subtract verwendet, um die asynchronen Rückrufe an den Client darzustellen.

Add(100,15.99)
Subtract(145,76.54)
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714
Add Result: 115.99
Subtract Result: 68.46

Thread-IDs werden beim Dienst verwendet, um zu demonstrieren, dass synchrone Aufrufe wie Add und Subtract von einem einzelnen Thread verarbeitet werden. Asynchrone Aufrufe wie Multiply und Divide schließen mehr als einen Thread ein. Die Dienstausgabe sieht wie folgt aus.

Received Add Synchronously on ThreadID 11:  Sleeping for 3 seconds
Asynchronous call: BeginMultiply on ThreadID 12
Received Subtract Synchronously on ThreadID 12:  Sleeping for 3 seconds
IO thread for * operation on ThreadID 13
EndMultiply called on ThreadID 14
Asynchronous call: BeginDivide on ThreadID 14
IO thread for / operation on ThreadID 13
EndDivide called on ThreadID 14
Returning Add Result on ThreadID 11
Returning Subtract Result on ThreadID 12

Das asynchrone .NET Framework-Muster kann entweder auf dem Client, dem Dienst oder beiden verwendet werden. Wie dieses Beispiel zeigt, sind die beiden Seiten unabhängig.

So richten Sie das Beispiel ein, erstellen es und führen es aus

  1. Vergewissern Sie sich, dass Sie die Einmaliges Setupverfahren für Windows Communication Foundation-Beispiele ausgeführt haben.

  2. Zum Erstellen der C#- oder Visual Basic .NET-Edition der Projektmappe befolgen Sie die unter Erstellen der Windows Communication Foundation-Beispiele aufgeführten Anweisungen.

  3. Wenn Sie das Beispiel in einer Konfiguration mit einem Computer oder über Computer hinweg ausführen möchten, folgen Sie den unter Running the Windows Communication Foundation Samples aufgeführten Anweisungen.

ms751505.Important(de-de,VS.100).gif Hinweis:
Die Beispiele sind möglicherweise bereits auf dem Computer installiert. Überprüfen Sie das folgende (standardmäßige) Verzeichnis, bevor Sie fortfahren.

<Installationslaufwerk>:\WF_WCF_Samples

Wenn dieses Verzeichnis nicht vorhanden ist, rufen Sie Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 auf, um alle Windows Communication Foundation (WCF)- und WF-Beispiele herunterzuladen. Dieses Beispiel befindet sich im folgenden Verzeichnis.

<Installationslaufwerk>:\WF_WCF_Samples\WCF\Basic\Contract\Service\Asynchronous