2012-12-08 28 views
9

My OperationContract:Làm thế nào để sử dụng Visual Studio - tạo ra các cuộc gọi WCF không đồng bộ?

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

Trong Dịch vụ cấu hình tham khảo tôi đã kiểm tra tùy chọn "Generate hoạt động không đồng bộ". Tôi làm cách nào để sử dụng GetMessagesAsync() được tạo ra? Trong net tôi tìm thấy các ví dụ sử dụng AsyncCallback, tuy nhiên tôi không quen thuộc với điều đó. Có cách nào để sử dụng nó một cách thân thiện như asyncawait từ khóa trong .NET 4.5 không? Nếu không, tôi nên làm gì để gọi phương thức không đồng bộ?

Trả lời

6

Nếu bạn chọn 'Tạo hoạt động asynchrounous', bạn sẽ nhận được các hành vi 'cũ', nơi bạn phải sử dụng callbacks.

Nếu bạn muốn sử dụng cú pháp async/await mới, bạn sẽ phải chọn 'Tạo các thao tác dựa trên tác vụ' (được chọn theo mặc định).

Khi sử dụng các mẫu WCF mặc định, điều này sẽ tạo ra các mã proxy sau:

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

Như bạn có thể thấy, có không callbacks. Thay vào đó, Task<T> được trả lại.

Bạn có thể sử dụng proxy này theo cách sau:

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

Bạn nên đánh dấu phương pháp gọi điện thoại với async và sau đó sử dụng await khi gọi phương thức dịch vụ của bạn.

+0

Tùy chọn "Tạo hoạt động dựa trên tác vụ" được bật nếu bạn đang sử dụng .NET V4.5 trở lên. –

+0

@ ManasKumar bạn có thể đăng bài đó dưới dạng câu hỏi riêng không? Điều đó sẽ cho phép mọi người trả lời nó. –

0

Làm thế nào về một cái gì đó như thế này ...

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

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

return t.Result; 

}

3

tham khảo dịch vụ của bạn có thể (nếu bạn đang sử dụng Net 4.5) được thiết lập để tạo ra các cuộc gọi async nhiệm vụ dựa trên. (Định cấu hình tham chiếu dịch vụ> kiểm tra Cho phép tạo các hoạt động không đồng bộ> chọn Tạo các thao tác dựa trên tác vụ) Có thể sử dụng các phương thức này như bất kỳ phương thức async nào. Dưới đây là ví dụ về cách sử dụng:

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

Nếu khách hàng của bạn không sử dụng .Net 4.5, bạn không thể tạo tham chiếu dịch vụ sử dụng async. Bạn sẽ phải làm điều đó theo cách cũ, sử dụng callbacks. Dưới đây là một ví dụ:

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

Lưu ý rằng trong mã thực tế đối với một trong những kịch bản này, bạn không nên sử dụng using hoặc IDisposable.Dispose() để làm sạch các khách hàng, xem Avoiding Problems with the Using Statementthis code để giúp bạn bắt đầu bước vào thế giới khó hiểu của bế mạc những thứ này.

1

Nếu bạn đang ở trên VS2012, sau đó bạn có thể sử dụng *Async cuộc gọi như thế này:

var proxy = new MyClient(); 
var result = await proxy.GetMessagesAsync(); 
Các vấn đề liên quan