Condividi tramite


One-Way

L'esempio unidirezionale illustra un'interfaccia di servizio con operazioni del servizio unidirezionali. Il client non aspetta che le operazioni di servizio siano completate, come avviene con le operazioni di servizio bidirezionali. Questo esempio si basa su Getting Started e usa l'associazione wsHttpBinding . Il servizio in questo esempio è un'applicazione console self-hosted che consente di osservare il servizio che riceve ed elabora le richieste. Il client è anche un'applicazione console.

Annotazioni

La procedura di installazione e le istruzioni di compilazione per questo esempio si trovano alla fine di questo argomento.

Per creare un contratto di servizio unidirezionale, definire il contratto di servizio, applicare la OperationContractAttribute classe a ogni operazione e impostare su IsOneWaytrue come illustrato nel codice di esempio seguente:

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

Per dimostrare che il client non attende il completamento delle operazioni del servizio, il codice del servizio in questo esempio implementa un ritardo di cinque secondi, come illustrato nel codice di esempio seguente:

// This service class implements the service contract.
// This code writes output to the console window.
 [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple,
    InstanceContextMode = InstanceContextMode.PerCall)]
public class CalculatorService : IOneWayCalculator
{
    public void Add(double n1, double n2)
    {
        Console.WriteLine("Received Add({0},{1}) - sleeping", n1, n2);
        System.Threading.Thread.Sleep(1000 * 5);
        double result = n1 + n2;
        Console.WriteLine("Processing Add({0},{1}) - result: {2}", n1, n2, result);
    }
    ...
}

Quando il client chiama il servizio, la chiamata viene restituita senza attendere il completamento dell'operazione del servizio.

Quando si esegue l'esempio, le attività client e di servizio vengono visualizzate sia nelle finestre del servizio che della console client. È possibile visualizzare il servizio che riceve messaggi dal client. Premere INVIO in ogni finestra della console per arrestare il servizio e il client.

Il client termina prima del servizio, dimostrando che un client non attende il completamento delle operazioni unidirezionali del servizio. L'output del client è il seguente:

Add(100,15.99)
Subtract(145,76.54)
Multiply(9,81.25)
Divide(22,7)

Press <ENTER> to terminate client.

Viene visualizzato l'output del servizio seguente:

The service is ready.
Press <ENTER> to terminate service.

Received Add(100,15.99) - sleeping
Received Subtract(145,76.54) - sleeping
Received Multiply(9,81.25) - sleeping
Received Divide(22,7) - sleeping
Processing Add(100,15.99) - result: 115.99
Processing Subtract(145,76.54) - result: 68.46
Processing Multiply(9,81.25) - result: 731.25
Processing Divide(22,7) - result: 3.14285714285714

Annotazioni

HTTP è, per definizione, un protocollo di richiesta/risposta; quando viene effettuata una richiesta, viene restituita una risposta. Questo vale anche per un'operazione di servizio unidirezionale esposta tramite HTTP. Quando viene chiamata l'operazione, il servizio restituisce un codice di stato HTTP 202 prima dell'esecuzione dell'operazione del servizio. Questo codice di stato indica che la richiesta è stata accettata per l'elaborazione, ma l'elaborazione non è ancora stata completata. Il client che ha chiamato l'operazione si blocca fino a quando non riceve la risposta 202 dal servizio. Ciò può causare un comportamento imprevisto quando vengono inviati più messaggi unidirezionale usando un'associazione configurata per l'uso delle sessioni. L'associazione wsHttpBinding usata in questo esempio è configurata per l'uso di sessioni per impostazione predefinita per stabilire un contesto di sicurezza. Per impostazione predefinita, i messaggi in una sessione sono garantiti per l'arrivo nell'ordine in cui vengono inviati. Per questo motivo, quando viene inviato il secondo messaggio in una sessione, non viene elaborato fino a quando non viene elaborato il primo messaggio. Il risultato è che il client non riceve la risposta 202 per un messaggio fino al completamento dell'elaborazione del messaggio precedente. Il client sembra quindi bloccarsi in ogni chiamata di operazione successiva. Per evitare questo comportamento, questo esempio configura il runtime per l'invio simultaneo di messaggi a istanze distinte per l'elaborazione. L'esempio imposta InstanceContextMode su PerCall in modo che ogni messaggio possa essere elaborato da un'istanza diversa. ConcurrencyMode è impostato su Multiple per consentire a più thread di inviare messaggi alla volta.

Per configurare, compilare ed eseguire l'esempio

  1. Assicurati di aver eseguito la procedura di installazione di One-Time per gli esempi di Windows Communication Foundation.

  2. Per compilare l'edizione C# o Visual Basic .NET della soluzione, seguire le istruzioni in Compilazione degli esempi di Windows Communication Foundation.

  3. Per eseguire l'esempio in una configurazione con computer singolo o incrociato, seguire le istruzioni riportate in Esecuzione degli esempi di Windows Communication Foundation.

Annotazioni

Eseguire il servizio prima di eseguire il client e arrestare il client prima di arrestare il servizio. In questo modo si evita un'eccezione client quando il client non può chiudere la sessione di sicurezza in modo pulito perché il servizio non è più disponibile.