Unidirektionale DiensteOne-Way Services

Das Standardverhalten eines Dienstvorgangs ist das Anforderung-Antwort-Muster.The default behavior of a service operation is the request-reply pattern. Bei einem Anforderung-Antwort-Muster wartet der Client auch dann auf die Antwortnachricht, wenn der Dienstvorgang im Code als void-Methode dargestellt wird.In a request-reply pattern, the client waits for the reply message, even if the service operation is represented in code as a void method. Mit einem unidirektionalen Vorgang wird nur eine Nachricht gesendet.With a one-way operation, only one message is transmitted. Der Empfänger sendet keine Antwortnachricht, und vom Absender wird keine erwartet.The receiver does not send a reply message, nor does the sender expect one.

Verwenden Sie das unidirektionale Entwurfsmuster:Use the one-way design pattern:

Bei einem unidirektionalen Vorgang gibt es keine Antwortnachricht, über die Fehlerinformationen zurück an den Client übertragen werden.When an operation is one-way, there is no response message to carry error information back to the client. Sie können Fehlerbedingungen mit den Funktionen der zugrunde liegenden Bindung, z. B. zuverlässige Sitzungen, ermitteln oder durch den Entwurf eines Duplexdienstvertrags, der zwei unidirektionale Vorgänge verwendet: einen unidirektionalen Vertrag vom Client zum Dienst zum Aufrufen von Dienstvorgängen sowie einen anderen unidirektionalen Vertrag zwischen dem Dienst und dem Client, damit der Dienst über einen vom Client implementierten Rückruf Fehler an den Client zurücksenden kann.You can detect error conditions by using features of the underlying binding, such as reliable sessions, or by designing a duplex service contract that uses two one-way operations—a one-way contract from the client to the service to call service operation and another one-way contract between the service and the client so that the service can send back faults to the client using a callback that the client implements.

Wenn Sie einen unidirektionalen Dienstvertrag erstellen möchten, wenden Sie die OperationContractAttribute-Klasse auf alle Vorgänge an, und legen Sie die IsOneWay-Eigenschaft auf true fest, wie im folgenden Beispielcode dargestellt.To create a one-way service contract, define your service contract, apply the OperationContractAttribute class to each operation, and set the IsOneWay property to true, as shown in the following sample code.

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]  
public interface IOneWayCalculator  
{  
    [OperationContract(IsOneWay=true)]  
    void Add(double n1, double n2);  
    [OperationContract(IsOneWay = true)]  
    void Subtract(double n1, double n2);  
    [OperationContract(IsOneWay = true)]  
    void Multiply(double n1, double n2);  
    [OperationContract(IsOneWay = true)]  
    void Divide(double n1, double n2);  
}  

Ein vollständiges Beispiel finden Sie unter der unidirektionale Beispiel.For a complete example, see the One-Way sample.

Clients, die mit unidirektionalen Vorgängen blockierenClients Blocking with One-Way Operations

Es ist wichtig zu beachten, dass zwar einige unidirektionalen Anwendungen zurückgegeben, sobald die ausgehenden Daten an die Netzwerkverbindung in anderen Fällen die Implementierung einer Bindung oder eines Diensts geschrieben ist ein WCF-Client mit unidirektionalen Vorgängen blockiert verursachen kann.It is important to realize that while some one-way applications return as soon as the outbound data is written to the network connection, in several scenarios the implementation of a binding or of a service can cause a WCF client to block using one-way operations. In WCF-Clientanwendungen gibt der WCF-Clientobjekts keinen zurück, bis die ausgehenden Daten an die Netzwerkverbindung geschrieben wurde.In WCF client applications, the WCF client object does not return until the outbound data has been written to the network connection. Dies gilt für alle Nachrichtenaustauschmuster, einschließlich unidirektionaler Vorgänge. Dies bedeutet, dass jedes Problem, das beim Schreiben der Daten an den Transport auftritt, verhindert, dass der Client zurückgegeben wird.This is true for all message exchange patterns, including one-way operations; this means that any problem writing the data to the transport prevents the client from returning. Je nach dem aufgetretenen Problem könnte das Ergebnis eine Ausnahme sein oder eine Verzögerung beim Senden der Nachrichten an den Dienst.Depending upon the problem, the result could be an exception or a delay in sending messages to the service.

Wenn der Transport z. B. den Endpunkt nicht finden kann, wird eine System.ServiceModel.EndpointNotFoundException-Ausnahme ohne große Verzögerung ausgelöst.For example, if the transport cannot find the endpoint, a System.ServiceModel.EndpointNotFoundException exception is thrown without much delay. Es kann jedoch auch vorkommen, dass der Dienst die Daten aus irgendeinem Grund nicht aus der Verbindung lesen kann. Dadurch wird verhindert, dass der Clienttransport-Sendevorgang zurückgegeben wird.However, it is also possible that the service is unable to read the data off the wire for some reason, which prevents the client transport send operation from returning. In diesen Fällen wird beim Überschreiten des Binding.SendTimeout-Zeitraums der Clienttransportbindung eine System.TimeoutException ausgelöst, jedoch nicht, bis der Timeoutzeitraum überschritten wurde.In these cases, if the Binding.SendTimeout period on the client transport binding is exceeded, a System.TimeoutException is thrown—but not until the timeout period has been exceeded. Es ist auch möglich, an einen Dienst so viele Nachrichten zu senden, dass diese nach einem bestimmten Punkt nicht vom Dienst verarbeitet werden können.It is also possible to fire so many messages at a service that the service cannot process them past a certain point. In diesem Fall blockiert der unidirektionale Client so lange, bis der Dienst die Nachrichten verarbeiten kann oder bis eine Ausnahme ausgelöst wird.In this case, too, the one-way client blocks until the service can process the messages or until an exception is thrown.

Eine andere Möglichkeit ist die Situation, in der die ServiceBehaviorAttribute.ConcurrencyMode-Diensteigenschaft auf Single festgelegt ist und die Bindung Sitzungen verwendet.Another variation is the situation in which the service ServiceBehaviorAttribute.ConcurrencyMode property is set to Single and the binding uses sessions. In diesem Fall erzwingt der Verteiler die Sortierung der eingehenden Nachrichten (eine Voraussetzung für Sitzungen), wodurch verhindert wird, dass die nachfolgenden Nachrichten aus dem Netzwerk gelesen werden, bis der Dienst die vorausgehende Nachricht für diese Sitzung verarbeitet hat.In this case, the dispatcher enforces ordering on the incoming messages (a requirement of sessions), which prevents subsequent messages from being read off the network until the service has processed the preceding message for that session. Der Client blockiert wiederum, aber ob eine Ausnahme stattfindet, richtet sich danach, ob die wartenden Daten vor den Timeouteinstellungen auf dem Client verarbeitet werden können.Again, the client blocks, but whether an exception occurs depends upon whether the service is able to process the waiting data prior to the timeout settings on the client.

Sie können dieses Problem verringern, indem Sie einen Puffer zwischen dem Clientobjekt und dem Sendevorgang des Clienttransports einfügen.You can mitigate some of this problem by inserting a buffer between the client object and the client transport's send operation. Wenn Sie z. B. asynchrone Anrufe oder eine Nachrichtenwarteschlange im Speicher verwenden, wird das Clientobjekt schnell zurückgegeben.For example, using asynchronous calls or using an in-memory message queue can enable the client object to return quickly. Beide Methoden erhöhen eventuell die Funktionalität, aber die Größe des Threadpools und der Nachrichtenwarteschlange erzwingen Beschränkungen.Both approaches may increase functionality, but the size of the thread pool and the message queue still enforce limits.

Es wird stattdessen empfohlen, die verschiedenen Steuerelemente des Diensts sowie des Clients zu prüfen, um eine optimale Konfiguration auf beiden Seiten zu gewährleisten.It is recommended, instead, that you examine the various controls on the service as well as on the client, and then test your application scenarios to determine the best configuration on either side. Wenn z. B. die Verwendung von Sitzungen die Verarbeitung von Nachrichten in Ihrem Dienst blockiert, können Sie die ServiceBehaviorAttribute.InstanceContextMode-Eigenschaft auf PerCall festlegen, damit die Nachrichten von einer anderen Dienstinstanz verarbeitet werden können. Außerdem können Sie den ConcurrencyMode auf Multiple festlegen, um das Senden von Nachrichten von mehr als einem Thread gleichzeitig zu erlauben.For example, if the use of sessions is blocking the processing of messages on your service, you can set the ServiceBehaviorAttribute.InstanceContextMode property to PerCall so that each message can be processed by a different service instance, and set the ConcurrencyMode to Multiple in order to allow more than one thread to dispatch messages at a time. Eine andere Methode besteht darin, die Lesekontingente des Diensts und der Clientbindungen zu erhöhen.Another approach is to increase the read quotas of the service and client bindings.

Siehe auchSee Also

UnidirektionalOne-Way