2012-12-08 5 views
9

Mein OperationContract:Wie verwendet man Visual Studio - generierte asynchrone WCF-Aufrufe?

public List<MessageDTO> GetMessages() 
     { 
      List<MessageDTO> messages = new List<MessageDTO>(); 
      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; 
     } 

In Service Referenz-Konfiguration überprüfte ich die Option "asynchrone Operationen erzeugen". Wie verwende ich das generierte GetMessagesAsync()? Im Netz habe ich Beispiele gefunden, die AsyncCallback verwenden, mir ist das aber nicht bekannt. Gibt es eine Möglichkeit, es in irgendeiner freundlichen Weise wie async und await Schlüsselwörter in .NET 4.5 zu verwenden? Wenn nicht, was soll ich tun, um die Methode asynchron aufzurufen?

Antwort

6

Wenn Sie ‚asynchrounous Operationen generieren‘ auswählen, werden Sie die ‚alte‘ Verhalten bekommen, wo Sie verwenden müssen Rückrufe.

Wenn Sie die neue async/await-Syntax verwenden möchten, müssen Sie 'Task-basierte Operationen generieren' auswählen (was standardmäßig ausgewählt ist).

Wenn die Standard-Wcf-Vorlage verwenden, wird dies den folgenden Proxy-Code generieren:

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

Wie Sie sehen können, gibt es keine mehr Rückrufe sind. Stattdessen wird Task<T> zurückgegeben.

Sie können diese Proxy auf folgende Weise verwenden:

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

Sie sollten die Rufmethode mit async markieren und dann await verwenden, wenn die Service-Methode aufrufen.

+0

Die Option "Task-basierte Operationen generieren" ist aktiviert, wenn Sie .NET V4.5 und höher verwenden. –

+0

@ManasKumar können Sie das als separate Frage buchen? Das wird den Leuten erlauben, es zu beantworten. –

0

Wie wäre es so etwas wie dieses ...

public async Task<string> DoSomething() 
{ 
var someProxy = new ServiceClient(); 

var t = someProxy.SomeMethodAsync(); 
await Task.WhenAny(t); 

return t.Result; 

}

3

Your Service Referenz kann (wenn Sie mit .Net 4.5) eingestellt werden Task-basierte asynchrone Anrufe zu generieren. (Konfigurieren Sie die Dienstreferenz> Aktivieren Sie die Option Generieren von asynchronen Vorgängen> wählen Sie aufgabenbasierte Vorgänge aus.) Diese können wie jede async Methode verwendet werden. Hier ist ein Beispiel dafür, wie es zu benutzen:

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

Wenn Ihr Kunde nicht .NET 4.5 können Sie nicht Service Referenzen erzeugen, die async verwenden. Sie müssen es auf altmodische Weise tun, indem Sie Rückrufe verwenden. Hier ein Beispiel:

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

Beachten Sie, dass in tatsächlichen Code für eine dieser beiden Szenarien Sie den Client nicht using oder IDisposable.Dispose() aufzuräumen verwenden sollten, finden Sie Avoiding Problems with the Using Statement und this code erhalten Sie in die verwirrende Welt der Schließung begonnen diese Dinge.

1

Wenn Sie auf VS2012 sind, dann können Sie die *Async Anrufe wie folgt verwenden:

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