Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Das Standardverhalten eines Dienstvorgangs ist das Anforderungsantwortmuster. Bei einem Anforderungsantwortmuster wartet der Client auf die Antwortnachricht, auch wenn der Dienstvorgang im Code als void
Methode dargestellt wird. Mit einem unidirektionalen Vorgang wird nur eine Nachricht gesendet. Der Empfänger sendet weder eine Antwortnachricht noch erwartet der Absender eine.
Verwenden Sie das unidirektionale Entwurfsmuster:
Wenn der Client Vorgänge aufrufen muss und vom Ergebnis des Vorgangs auf Vorgangsebene nicht betroffen ist.
Bei Verwendung der NetMsmqBinding Klasse oder der MsmqIntegrationBinding Klasse. (Weitere Informationen zu diesem Szenario finden Sie unter Warteschlangen in WCF.)
Wenn ein Vorgang unidirektional ist, gibt es keine Antwortmeldung, die Fehlerinformationen an den Client zurückgeben kann. Sie können Fehlerzustände erkennen, indem Sie Funktionen der zugrunde liegenden Bindung, wie z. B. zuverlässige Sitzungen, nutzen oder einen Duplex-Dienstvertrag entwerfen, der zwei unidirektionale Verträge verwendet – einen unidirektionalen Vertrag vom Client zum Dienst für den Aufruf des Dienstvorgangs und einen weiteren unidirektionalen Vertrag zwischen dem Dienst und dem Client, damit der Dienst Fehler mithilfe eines Rückrufs, den der Client implementiert, an den Client zurücksenden kann.
Um einen Unidirektionalen Servicevertrag zu erstellen, definieren Sie Ihren Servicevertrag, wenden Sie die OperationContractAttribute-Klasse auf jede Operation an und legen Sie die IsOneWay-Eigenschaft auf true
fest, wie es im Beispielcode unten gezeigt wird.
[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 im One-Way-Beispiel .
Clients, die mit unidirektionalen Vorgängen blockieren
Sie sollten unbedingt berücksichtigen, dass zwar einige unidirektionale Anwendungen gleich nach dem Schreiben der ausgehenden Daten an die Netzwerkverbindung zurückgegeben werden, in anderen Fällen die Implementierung einer Bindung oder eines Diensts jedoch dazu führen kann, dass ein WCF-Client mit unidirektionalen Vorgängen blockiert. In WCF-Clientanwendungen wird das WCF-Clientobjekt erst zurückgegeben, wenn die ausgehenden Daten in die Netzwerkverbindung geschrieben wurden. 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. Je nach Problem kann das Ergebnis eine Ausnahme oder eine Verzögerung beim Senden von Nachrichten an den Dienst sein.
Wenn der Transport beispielsweise den Endpunkt nicht finden kann, wird eine System.ServiceModel.EndpointNotFoundException Ausnahme ohne viel Verzögerung ausgelöst. 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. 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. Es ist auch möglich, so viele Nachrichten an einem Dienst auszulösen, dass der Dienst sie nicht über einen bestimmten Punkt verarbeiten kann. In diesem Fall blockiert auch der unidirektionale Client, bis der Dienst die Nachrichten verarbeiten kann oder bis eine Ausnahme ausgelöst wird.
Eine andere Möglichkeit ist die Situation, in der die ServiceBehaviorAttribute.ConcurrencyMode-Diensteigenschaft auf Single festgelegt ist und die Bindung Sitzungen verwendet. In diesem Fall erzwingt der Verteiler die Sortierung der eingehenden Nachrichten (eine Anforderung 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. 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.
Sie können einige dieser Probleme beheben, indem Sie einen Puffer zwischen dem Clientobjekt und dem Sendevorgang des Clienttransports einfügen. Wenn Sie z. B. asynchrone Aufrufe verwenden oder eine In-Memory-Nachrichtenwarteschlange verwenden, kann das Clientobjekt schnell zurückgegeben werden. Beide Ansätze können die Funktionalität erhöhen, aber die Größe des Threadpools und die Nachrichtenwarteschlange erzwingen weiterhin Grenzwerte.
Es wird stattdessen empfohlen, die verschiedenen Steuerelemente auf dem Dienst sowie auf dem Client zu untersuchen und dann Ihre Anwendungsszenarien zu testen, um die beste Konfiguration auf beiden Seiten zu ermitteln. Wenn die Verwendung von Sitzungsverwaltung z. B. die Verarbeitung von Nachrichten in Ihrem Dienst blockiert, können Sie die ServiceBehaviorAttribute.InstanceContextMode Eigenschaft PerCall so festlegen, dass jede Nachricht von einer anderen Dienstinstanz verarbeitet werden kann, und die Eigenschaft ConcurrencyMode auf Multiple festlegen, damit mehrere Threads gleichzeitig Nachrichten verteilen können. Eine andere Methode besteht darin, die Lesekontingente des Diensts und der Clientbindungen zu erhöhen.