One-Way Services
Het standaardgedrag van een servicebewerking is het patroon aanvraag-antwoord. In een aanvraag-antwoordpatroon wacht de client op het antwoordbericht, zelfs als de servicebewerking als een void
methode in code wordt weergegeven. Met een eenrichtingsbewerking wordt slechts één bericht verzonden. De ontvanger verzendt geen antwoordbericht, noch verwacht de afzender er een.
Gebruik het ontwerppatroon in één richting:
Wanneer de client bewerkingen moet aanroepen en niet wordt beïnvloed door het resultaat van de bewerking op bewerkingsniveau.
Wanneer u de NetMsmqBinding of de MsmqIntegrationBinding klasse gebruikt. (Zie voor meer informatie over dit scenario Wachtrijen in WCF.)
Wanneer een bewerking in één richting is, is er geen antwoordbericht om foutinformatie terug te brengen naar de client. U kunt foutvoorwaarden detecteren met behulp van functies van de onderliggende binding, zoals betrouwbare sessies, of door een dubbelzijdig servicecontract te ontwerpen dat gebruikmaakt van tweerichtingsbewerkingen: een eenrichtingscontract van de client naar de service om servicebewerking aan te roepen en een ander eenrichtingscontract tussen de service en de client, zodat de service fouten naar de client kan terugsturen met behulp van een callback die de client implementeert.
Als u een eenrichtingsservicecontract wilt maken, definieert u uw servicecontract, past u de OperationContractAttribute klasse toe op elke bewerking en stelt u de IsOneWay eigenschap true
in op , zoals wordt weergegeven in de volgende voorbeeldcode.
[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);
}
Zie het one-way-voorbeeld voor een volledig voorbeeld.
Clients die blokkeren met bewerkingen in één richting
Het is belangrijk om te beseffen dat sommige toepassingen in één richting retourneren zodra de uitgaande gegevens naar de netwerkverbinding worden geschreven, in verschillende scenario's de implementatie van een binding of een service ertoe kan leiden dat een WCF-client wordt geblokkeerd met behulp van bewerkingen in één richting. In WCF-clienttoepassingen wordt het WCF-clientobject pas geretourneerd als de uitgaande gegevens naar de netwerkverbinding zijn geschreven. Dit geldt voor alle patronen voor het uitwisselen van berichten, waaronder bewerkingen in één richting; dit betekent dat elk probleem bij het schrijven van de gegevens naar het transport verhindert dat de klant terugkeert. Afhankelijk van het probleem kan het resultaat een uitzondering zijn of een vertraging bij het verzenden van berichten naar de service.
Als het eindpunt bijvoorbeeld niet kan worden gevonden, wordt er zonder veel vertraging een System.ServiceModel.EndpointNotFoundException uitzondering gegenereerd. Het is echter ook mogelijk dat de service om een of andere reden de gegevens van de kabel niet kan lezen, waardoor de verzendbewerking van het clienttransport niet kan worden geretourneerd. In dergelijke gevallen, als de Binding.SendTimeout periode op de clienttransportbinding wordt overschreden, wordt er een System.TimeoutException gegenereerd, maar niet totdat de time-outperiode is overschreden. Het is ook mogelijk om zoveel berichten te activeren bij een service dat de service ze niet op een bepaald punt kan verwerken. In dit geval blokkeert de eenrichtingsclient ook totdat de service de berichten kan verwerken of totdat er een uitzondering wordt gegenereerd.
Een andere variatie is de situatie waarin de service-eigenschap ServiceBehaviorAttribute.ConcurrencyMode is ingesteld Single en de binding sessies gebruikt. In dit geval dwingt de dispatcher de volgorde af voor de inkomende berichten (een vereiste van sessies), waardoor volgende berichten niet van het netwerk kunnen worden gelezen totdat de service het voorgaande bericht voor die sessie heeft verwerkt. De client blokkeert opnieuw, maar of er een uitzondering optreedt, is afhankelijk van of de service de wachtgegevens kan verwerken vóór de time-outinstellingen van de client.
U kunt een deel van dit probleem oplossen door een buffer in te voegen tussen het clientobject en de verzendbewerking van het clienttransport. Als u bijvoorbeeld asynchrone aanroepen gebruikt of een berichtenwachtrij in het geheugen gebruikt, kan het clientobject snel terugkeren. Beide benaderingen kunnen de functionaliteit vergroten, maar de grootte van de threadgroep en de berichtenwachtrij dwingen nog steeds limieten af.
Het wordt aanbevolen om in plaats daarvan de verschillende besturingselementen voor de service en de client te onderzoeken en vervolgens uw toepassingsscenario's te testen om de beste configuratie aan beide zijden te bepalen. Als het gebruik van sessies bijvoorbeeld de verwerking van berichten op uw service blokkeert, kunt u de ServiceBehaviorAttribute.InstanceContextMode eigenschap PerCall zo instellen dat elk bericht kan worden verwerkt door een ander service-exemplaar en de ConcurrencyModeMultiple optie zo instellen dat meerdere threads tegelijk berichten kunnen verzenden. Een andere benadering is het verhogen van de leesquota van de service- en clientbindingen.