Dela via


Enkelriktade tjänster

Standardbeteendet för en tjänståtgärd är mönstret för begäran-svar. I ett mönster för begäran-svar väntar klienten på svarsmeddelandet, även om tjänståtgärden representeras i kod som en void metod. Med en enkelriktad åtgärd överförs bara ett meddelande. Mottagaren skickar inget svarsmeddelande och avsändaren förväntar sig inte heller något.

Använd envägsdesignmönstret:

  • När klienten måste anropa åtgärder och inte påverkas av resultatet av åtgärden på åtgärdsnivå.

  • När du använder NetMsmqBinding klassen eller MsmqIntegrationBinding . (Mer information om det här scenariot finns i Köer i WCF.)

När en åtgärd är enkelriktad finns det inget svarsmeddelande för att överföra felinformation tillbaka till klienten. Du kan identifiera felvillkor med hjälp av funktioner i den underliggande bindningen, till exempel tillförlitliga sessioner, eller genom att utforma ett duplex-tjänstkontrakt som använder två enkelriktade åtgärder– ett enkelriktat kontrakt från klienten till tjänsten för att anropa tjänståtgärden och ett annat enkelriktat kontrakt mellan tjänsten och klienten så att tjänsten kan skicka tillbaka fel till klienten med hjälp av ett återanrop som klienten implementerar.

Om du vill skapa ett envägstjänstkontrakt definierar du ditt tjänstkontrakt, tillämpar OperationContractAttribute klassen på varje åtgärd och anger IsOneWay egenskapen till true, enligt följande exempelkod.

[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);  
}  

Ett fullständigt exempel finns i exemplet enkelriktad.

Klienter som blockerar med enkelriktade åtgärder

Det är viktigt att inse att även om vissa enkelriktade program returnerar så snart utgående data skrivs till nätverksanslutningen, kan implementeringen av en bindning eller en tjänst i flera scenarier leda till att en WCF-klient blockeras med hjälp av enkelriktade åtgärder. I WCF-klientprogram returneras inte WCF-klientobjektet förrän utgående data har skrivits till nätverksanslutningen. Detta gäller för alla mönster för meddelandeutbyte, inklusive enkelriktade åtgärder. Det innebär att eventuella problem med att skriva data till transporten hindrar klienten från att återvända. Beroende på problemet kan resultatet bli ett undantag eller en fördröjning när meddelanden skickas till tjänsten.

Om transporten till exempel inte kan hitta slutpunkten utlöses ett System.ServiceModel.EndpointNotFoundException undantag utan mycket fördröjning. Det är dock också möjligt att tjänsten inte kan läsa data från tråden av någon anledning, vilket förhindrar att klienttransportens sändningsåtgärd returneras. I dessa fall, om Binding.SendTimeout perioden för klienttransportbindningen överskrids, utlöses en System.TimeoutException , men inte förrän tidsgränsen har överskridits. Det är också möjligt att utlösa så många meddelanden i en tjänst att tjänsten inte kan bearbeta dem förbi en viss punkt. I det här fallet blockerar även enkelriktad klient tills tjänsten kan bearbeta meddelandena eller tills ett undantag utlöses.

En annan variant är den situation där tjänstegenskapen ServiceBehaviorAttribute.ConcurrencyMode är inställd på Single och bindningen använder sessioner. I det här fallet framtvingar avsändaren ordning på inkommande meddelanden (ett krav på sessioner), vilket förhindrar att efterföljande meddelanden läse av nätverket tills tjänsten har bearbetat föregående meddelande för sessionen. Återigen blockerar klienten, men om ett undantag inträffar beror på om tjänsten kan bearbeta väntande data före tidsgränsinställningarna på klienten.

Du kan åtgärda en del av det här problemet genom att infoga en buffert mellan klientobjektet och klienttransportens sändningsåtgärd. Om du till exempel använder asynkrona anrop eller använder en minnesintern meddelandekö kan klientobjektet snabbt returneras. Båda metoderna kan öka funktionaliteten, men storleken på trådpoolen och meddelandekön framtvingar fortfarande begränsningar.

Vi rekommenderar i stället att du undersöker de olika kontrollerna för tjänsten och på klienten och sedan testar dina programscenarier för att fastställa den bästa konfigurationen på båda sidor. Om användningen av sessioner till exempel blockerar bearbetningen av meddelanden i tjänsten kan du ange ServiceBehaviorAttribute.InstanceContextMode egenskapen till PerCall så att varje meddelande kan bearbetas av en annan tjänstinstans och ange ConcurrencyMode till Multiple för att tillåta att fler än en tråd skickar meddelanden åt gången. En annan metod är att öka läskvoterna för tjänsten och klientbindningarna.

Se även