2012-12-08 15 views
9

mio OperationContract:Come utilizzare Visual Studio: chiamate WCF asincrone generate?

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 configurazione di riferimento ho controllato l'opzione "Genera operazioni asincrone". Come posso utilizzare lo GetMessagesAsync() generato? Nella rete ho trovato esempi che usano AsyncCallback, tuttavia non mi è familiare. C'è un modo per usarlo in modo amichevole come le parole chiave async e await in .NET 4.5? In caso contrario, cosa devo fare per richiamare il metodo in modo asincrono?

risposta

6

Se si seleziona 'Genera asincrono operazioni', si otterrà il comportamento 'vecchio' in cui devi usare callback.

Se si desidera utilizzare la nuova sintassi asincrona/attesa, è necessario selezionare "Genera operazioni basate sulle attività" (che è selezionata per impostazione predefinita).

Quando si utilizza il modello Wcf impostazione predefinita, questa genererà il seguente codice proxy:

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

Come si può vedere, non ci sono più callback. Invece viene restituito un Task<T>.

È possibile utilizzare questo proxy nel seguente modo:

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

Si dovrebbe contrassegnare il metodo chiamante con async e quindi utilizzare await quando si chiama il metodo di servizio.

+0

L'opzione "Genera operazioni basate su attività" è abilitata se si utilizza .NET V4.5 e versioni successive. –

+0

@ManasKumar puoi postarlo come una domanda separata? Ciò consentirà alle persone di rispondere. –

0

Che ne dite di qualcosa di simile ...

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

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

return t.Result; 

}

3

vostro riferimento servizio può (se si utilizza Net 4.5) essere impostato per generare le chiamate asincrone basate su attività. (Configura riferimento servizio> selezionare Consenti generazione di operazioni asincrone> selezionare Genera operazioni basate su operazioni) Questi possono essere usati come qualsiasi metodo async. Ecco un esempio di come usarlo:

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

Se il cliente non utilizza .Net 4.5, non è possibile generare i riferimenti di servizi che utilizzano async. Dovrai farlo alla vecchia maniera, usando i callback. Ecco un esempio:

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

Si noti che nel codice vero e proprio per uno di questi scenari, non si dovrebbe usare using o IDisposable.Dispose() per ripulire il client, vedere Avoiding Problems with the Using Statement e this code per iniziare nel mondo confuso di chiusura queste cose.

1

Se siete su VS2012, quindi è possibile utilizzare le *Async chiamate come questo:

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