Condividi tramite


Asincrono

L'esempio Contratto di servizio asincrono mostra come un client può accedere in modo asincrono a un'operazione del servizio e come un servizio può implementare in modo asincrono le operazioni. L'esempio è basato su Esempio della guida introduttiva, che implementa un servizio di calcolatrice. L'utilizzo di chiamate sincrone o asincrone è una decisione locale e non ha impatto su messaggi inviati via cavo. Anche se il servizio implementa alcune operazioni sincrone, il client può accedere in modo asincrono alle operazioni del servizio. Anche se il client chiama il servizio in modo sincrono, il servizio può implementare in modo asincrono alcune operazioni.

ms751505.note(it-it,VS.100).gifNota:
La procedura di installazione e le istruzioni di compilazione per questo esempio si trovano alla fine dell'argomento.

In questo esempio, il client è un'applicazione console (.exe) e il servizio è un servizio indipendente ospitato in un'applicazione console (.exe).

Il servizio implementa l'interfaccia ICalculator. Il client può chiamare le operazioni in questa interfaccia in modo asincrono, vale a dire che operazioni come Add ora hanno BeginAdd e EndAdd.

ms751505.note(it-it,VS.100).gifNota:
Vedere la documentazione di .NET Framework per ulteriori dettagli sul modello asincrono.

Il client ha generato codice che supporta le operazioni asincrone. Il client è stato creato eseguendo lo strumento Strumento ServiceModel Metadata Utility Tool (Svcutil.exe) con l'opzione di comando /a (async), come segue:

svcutil /n:http://Microsoft.ServiceModel.Samples,Microsoft.ServiceModel.Samples https://localhost:8000/servicemodelsamples/service/mex /a /tcv:Version35

La versione client asincrona del contratto di servizio per l'operazione Add è simile al codice di esempio seguente.

[System.ServiceModel.ServiceContractAttribute(Namespace=
                   "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [System.ServiceModel.OperationContractAttribute(
       AsyncPattern=true)]
    System.IAsyncResult BeginAdd(double n1, double n2, 
                   System.AsyncCallback callback, object asyncState);
    double EndAdd(System.IAsyncResult result);
    
    ...
}

Quando l'opzione /tcv:Version35 viene specificata insieme all'opzione /async, il tipo client generato implementa il modello asincrono basato su eventi per chiamare il servizio. Per ulteriori informazioni, vedere Cenni preliminari sul modello asincrono basato su eventi. Per accedere in modo asincrono a un'operazione del servizio, l'applicazione aggiunge un gestore di eventi all'evento [Operation]Completed sul client e quindi chiama il metodo [Operation]Async (ad esempio, AddAsync) come mostra il codice di esempio seguente.

// Create a client.
CalculatorClient client = new CalculatorClient();

// BeginAdd.
double value1 = 100.00D;
double value2 = 15.99D;

client.AddCompleted += new EventHandler<AddCompletedEventArgs>(AddCallback);
client.AddAsync(value1, value2);

Nell'esempio, il client avvia in modo asincrono due operazioni: Add e Subtract.

Quando la funzione di callback viene eseguita, il client accede alla proprietà Result sul parametro di input [Operation]CompletedEventArgs per recuperare il risultato.

static void AddCallback(object sender, AddCompletedEventArgs e)
{
 Console.WriteLine("Add Result: {0}", e.Result);
}

Ogni comportamento asincrono è locale per il client e non è rilevante per la modalità in cui i messaggi sono inviati dal client o elaborati dal servizio. La ragione tipica per utilizzare questo modello in un'applicazione di interfaccia utente è mantenere il thread dell'interfaccia utente libero, per aggiornare lo schermo. Questo modello può essere applicato anche quando un servizio si sta comportando come un client e si vuole esonerare il thread di elaborazione dei messaggi dalle chiamate ad altri servizi. La prossima sezione mostra come rendere asincrone operazioni di un servizio.

Il servizio implementa l'interfaccia ICalculator, come illustrato nel codice seguente.

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
    [OperationContract]
    double Add(double n1, double n2);
    
    [OperationContract]
    double Subtract(double n1, double n2);
    
    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginMultiply(double n1, double n2,
        AsyncCallback callback, object state);
    double EndMultiply(IAsyncResult ar);

    [OperationContract(AsyncPattern = true)]
    IAsyncResult BeginDivide(double n1, double n2, 
        AsyncCallback callback, object state);
    double EndDivide(IAsyncResult ar); 
}

Le prime due operazioni del contratto vengono richiamate in modo sincrono dal runtime di Windows Communication Foundation (WCF). Le ultime due coppie di operazioni vengono utilizzate per richiamare in modo asincrono il servizio. In questo esempio la proprietà AsyncPattern viene impostata su true. Tale impostazione della proprietà, in combinazione con l'implementazione del modello asincrono di .NET Framework, consente al runtime di richiamare in modo asincrono l'operazione.

La ragione per utilizzare questo modello nell'implementazione di un servizio è, in genere, liberare il thread di elaborazione dei messaggi quando si effettuano lunghe operazioni di input e output quali accesso al disco, accesso a un database o chiamata a un altro servizio. Questo esempio illustra come eseguire le operazioni di wrapping di input e output con un'implementazione di IAsyncResult. La classe di base per l'implementazione della classe MathAsyncResult può essere riutilizzata per scrivere implementazioni di IAsyncResult.

ms751505.note(it-it,VS.100).gifNota:
Questo esempio utilizza PerCall e Multiple per impedire il comportamento di ordinazione arriva con un'associazione di sessione. Il wsHttpBinding utilizza una sessione per impostazione predefinita stabilire un contesto di sicurezza. Questo non influisce sulla natura asincrona del messaggio elaborato dal client o dal servizio, ma enfatizza il tempo di risposta e consente al client di osservare callback simultanei, anziché seriali.

Quando si esegue l'esempio, le richieste e le risposte dell'operazione vengono visualizzate nella finestra della console client. Le richieste Add e Subtract non vengono bloccate perché sono richiamate in modo asincrono. Quindi le operazioni Multiply e Divide si bloccano e i risultati vengono visualizzati in contemporanea all'invio delle richieste. Infine, i risultati delle operazioni Add e Subtract vengono visualizzati sono nuovamente restituiti al client. sleep viene utilizzato nell'implementazione del servizio Add e Subtract per mostrare i callback asincroni sul client.

Add(100,15.99)
Subtract(145,76.54)
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714
Add Result: 115.99
Subtract Result: 68.46

Gli id del thread sono utilizzati nel servizio per dimostrare che chiamate sincrone, ad esempio Add e Subtract, sono gestite in un solo thread. Chiamate asincrone, ad esempio Multiply e Divide, comportano più di un thread. L'output del servizio è simile al seguente.

Received Add Synchronously on ThreadID 11:  Sleeping for 3 seconds
Asynchronous call: BeginMultiply on ThreadID 12
Received Subtract Synchronously on ThreadID 12:  Sleeping for 3 seconds
IO thread for * operation on ThreadID 13
EndMultiply called on ThreadID 14
Asynchronous call: BeginDivide on ThreadID 14
IO thread for / operation on ThreadID 13
EndDivide called on ThreadID 14
Returning Add Result on ThreadID 11
Returning Subtract Result on ThreadID 12

Il modello asincrono di .NET Framework può essere utilizzato sul client, sul servizio, o su entrambi. Come mostra questo esempio, i due lati sono indipendenti.

Per impostare, compilare ed eseguire l'esempio

  1. Verificare di avere eseguito Procedura di installazione singola per gli esempi di Windows Communication Foundation.

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

  3. Per eseguire l'esempio in una configurazione con un solo computer o tra computer diversi, seguire le istruzioni in Running the Windows Communication Foundation Samples.

ms751505.Important(it-it,VS.100).gif Nota:
È possibile che gli esempi siano già installati nel computer. Verificare la directory seguente (impostazione predefinita) prima di continuare.

<UnitàInstallazione>:\WF_WCF_Samples

Se questa directory non esiste, andare alla pagina relativa agli esempi di Windows Communication Foundation (WCF) e Windows Workflow Foundation (WF) per .NET Framework 4 per scaricare tutti gli esempi di Windows Communication Foundation (WCF) e WF. Questo esempio si trova nella directory seguente.

<UnitàInstallazione>:\WF_WCF_Samples\WCF\Basic\Contract\Service\Asynchronous