Chiamare metodi asincroni da un servizio WCF

Voglio chiamare metodi asincroni da un servizio WCF, qualcosa del tipo:

[ServiceContract] interface IService { [OperationContract] int SomeMethod(int data); } int SomeMethod(int data) { var query = ... build LINQ query; var response = await query.ToListAsync(); return response.Length; } 

Non voglio aggiungere async all’interfaccia IService o SomeMethod metodo SomeMethod . L’utilizzo di metodi asincroni è un problema interno che non dovrebbe riflettersi nell’interfaccia.

Come lo posso fare?

UNA PRECISAZIONE:

Il mio problema qui è quello di await in un metodo non async . Non voglio che il contratto di servizio cambi (il client non sa necessariamente cosa sia async ), e non voglio dividere il metodo in BeginSomeMethod e EndSomeMethod . Voglio che un metodo che usi await internamente .

Se il server utilizza la sincronizzazione o il codice asincrono non ha importanza per il client. Client e server sono separati da un protocollo wire ben specificato (spesso SOAP). SOAP non ha nozioni sul completamento asincrono.

È ansible avere un server di sincronizzazione e un client asincrono o viceversa. Il client non può nemmeno rilevare se il server è sincronizzato o asincrono. Questo è un dettaglio di implementazione. Il server potrebbe essere un orologio da polso con Linux e non si può ancora dire.

Lo stile di IO che utilizzi è un dettaglio di implementazione e non influenza i byte che attraversano la rete.

Quindi scegli quello che ti piace. Il client può ancora utilizzare IO asincrono per accedere al server.

Non sono sicuro del motivo per cui questa è una sorpresa per le persone. In altri contesti questo sembra molto intuitivo: puoi avere un server TCP asincrono e un client sincrono. Posso dire new WebClient().DownloadString(url) e scaricare una stringa in modo sincrono da un server web implementato in modo asincrono. Non posso nemmeno dire quale software del server è in esecuzione.

Usa Fiddler per vedere cosa succede sul filo quando fai una chiamata WCF. Non esiste la nozione di chiamate sincrone o asincrone.

Sotto il cofano, quando si richiama un servizio in modo asincrono, la libreria client WCF utilizza socket TCP in modo asincrono. Quando si invoca in modo sincrono, i socket TCP vengono utilizzati con le chiamate di blocco. Questa è l’intera differenza.

I client generati da WCF possono essere realizzati per avere metodi asincroni oltre ai metodi sincroni. Seleziona l’opzione “Genera operazioni asincrone” nell’interfaccia utente. Ora hai entrambe le versioni. Entrambi perfettamente funzionanti.

Ecco come puoi convincere te stesso con un esperimento: scrivi un server di sincronizzazione e chiamalo sia sync che async dallo stesso client .NET. Ora scrivi un secondo server in modo asincrono (in qualsiasi stile tu voglia) e usa lo stesso identico codice client per chiamarlo.

Task e IAsyncResult non sono serializzabili su SOAP in ogni caso, quindi non può essere il caso che un Task sia trasmesso al client.