Comment utiliser les appels WCF asynchrones générés par Visual Studio?

Mon OperationContract :

 public List GetMessages() { List messages = new List(); foreach (Message m in _context.Messages.ToList()) { messages.Add(new MessageDTO() { MessageID = m.MessageID, Content = m.Content, Date = m.Date, HasAttachments = m.HasAttachments, MailingListID = (int)m.MailingListID, SenderID = (int)m.SenderID, Subject = m.Subject }); } return messages; } 

Dans la configuration du service de référence, j’ai coché l’option “Générer des opérations asynchrones”. Comment utiliser le GetMessagesAsync() généré? Sur le net, j’ai trouvé des exemples qui utilisent AsyncCallback , mais je ne suis pas au courant de cela. Existe-t-il un moyen de l’utiliser de manière conviviale, comme async et d’ await mots-clés dans .NET 4.5? Si non, que dois-je faire pour appeler la méthode de manière asynchrone?

Si vous sélectionnez “Générer des opérations asynchrones”, vous obtiendrez le “vieux” comportement dans lequel vous devez utiliser des rappels.

Si vous souhaitez utiliser la nouvelle syntaxe async / wait, vous devez sélectionner «Générer des opérations basées sur des tâches» (sélectionné par défaut).

Lorsque vous utilisez le modèle Wcf par défaut, cela génère le code proxy suivant:

  public System.Threading.Tasks.Task GetDataAsync(int value) { return base.Channel.GetDataAsync(value); } 

Comme vous pouvez le constater, il n’y a plus de rappels. À la place, une Task est renvoyée.

Vous pouvez utiliser ce proxy de la manière suivante:

 public static async Task Foo() { using (ServiceReference1.Service1Client client = new ServiceReference1.Service1Client()) { Task t = client.GetDataAsync(1); ssortingng result = await t; } } 

Vous devez marquer la méthode d’appel avec async , puis utiliser await lorsque vous appelez votre méthode de service.

Votre référence de service peut (si vous utilisez .Net 4.5) être configurée pour générer des appels asynchrones basés sur des tâches. (Configurez la référence de service> activez la case à cocher Autoriser la génération d’opérations asynchrones> sélectionnez Générer des opérations basées sur des tâches). Ces opérations peuvent être utilisées comme n’importe quelle méthode async . Voici un exemple d’utilisation:

 using (var proxy = new YourServiceClient()) { var t1 = proxy.GetMessagesAsync(); var t2 = proxy.GetMessagesAsync(); //they're runnning asynchronously now! //let's wait for the results: Task.WaitAll(t1, t2); var result1 = t1.Result; var result2 = t2.Result; Console.WriteLine(result1); Console.WriteLine(result2); } 

Si votre client n’utilise pas .Net 4.5, vous ne pouvez pas générer de références de service utilisant async . Vous devrez le faire à l’ancienne, en utilisant des rappels. Voici un exemple:

 static void m() { var proxy = new YourServiceClient(); proxy.GetMessagesCompleted += proxy_GetMessagesCompleted; proxy.GetMessagesAsync(); } static void proxy_GetMessagesCompleted(object sender, GetMessagesCompletedEventArgs e) { var proxy = (IDisposable)sender; proxy.Dispose(); //actual code to close properly is more complex if (e.Error != null) { // do something about this } var result = e.Result; Console.WriteLine(result); } 

Notez que dans le code réel de l’un ou l’autre de ces scénarios, vous ne devez pas utiliser using ou IDisposable.Dispose() pour nettoyer le client. des choses.

Si vous êtes sur VS2012, vous pouvez utiliser les appels *Async comme ceci:

 var proxy = new MyClient(); var result = await proxy.GetMessagesAsync(); 

Que diriez-vous quelque chose comme ça…

 public async Task DoSomething() { var someProxy = new ServiceClient(); var t = someProxy.SomeMethodAsync(); await Task.WhenAny(t); return t.Result; 

}