2012-12-08 19 views
9

OperationContract如何使用Visual Studio生成的異步WCF調用?

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

在服務的參考配置我查了選項「生成異步操作」。我如何使用生成的GetMessagesAsync()?在網絡中,我找到了使用AsyncCallback的例子,但是我對此並不熟悉。有沒有辦法在.NET 4.5中以一些友好的方式使用它,如asyncawait關鍵字?如果不是,我應該如何異步調用該方法?

回答

6

如果選擇「生成 - 異步操作」,你會得到「老」的行爲,你必須使用回調。

如果您要使用新的異步/等待語法,則必須選擇「生成基於任務的操作」(默認情況下爲選中)。

當使用缺省模板週轉基金,這會產生以下代理代碼:

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

正如你所看到的,有沒有更多的回調。而是返回Task<T>

您可以通過以下方式使用代理:

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

你應該標記與async調用方法,然後調用服務方法時使用await

+0

如果您使用的是.NET V4.5及更高版本,則將啓用「生成基於任務的操作」選項。 –

+0

@ManasKumar你可以作爲一個單獨的問題嗎?這將允許人們回答它。 –

0

如何這樣的事情...

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

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

return t.Result; 

}

3

您的服務可以參考(如果你使用的是.NET 4.5)設置生成基於任務的異步調用。 (配置服務參考>選中允許生成異步操作>選擇生成基於任務的操作)這些可以像任何async方法一樣使用。這裏有一個如何使用它的一個例子:

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

如果您的客戶端不使用.NET 4.5,則無法生成使用async服務引用。您必須以舊式的方式使用回調。這裏有一個例子:

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

注意,在這兩種情況下的實際代碼,你不應該使用usingIDisposable.Dispose()清理客戶端,請參閱Avoiding Problems with the Using Statementthis code讓你開始到結束的混亂世界這些東西。

1

如果你在VS2012,那麼你可以使用*Async調用是這樣的:

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