2013-03-13 41 views
6

Tôi có một dịch vụ di sản WCF với một số lượng hợp đồng hoạt động One-Way thực hiện theo cách cổ điển nhất:một chiều async/chờ đợi cuộc gọi trong WCF

// The interface 
    [OperationContract(IsOneWay = true, AsyncPattern = true)] 
    IAsyncResult BeginFinalizePublishing(PageContent pageContent, AsyncCallback callback, object asyncState); 
    void EndFinalizePublishing(IAsyncResult result); 

    // The service 
    public IAsyncResult BeginFinalizePublishing(PageContent pageContent, AsyncCallback callback, object asyncState) 
    {...} 

Vì vậy, tất cả mọi thứ hoạt động tốt ở đây, bây giờ tôi cần để chuyển đổi thành C# 5 mẫu không đồng bộ/chờ đợi mới nhất. Chú ý đến tính chất một chiều của các hoạt động. Câu hỏi của tôi:

  • Tôi đoán tôi cần xóa AsyncPattern = true khỏi thuộc tính OperationContract.
  • Thay thế loại trả về IAsyncResult bằng void trong giao diện và async void trong lớp học.
  • Xóa đầu/cuối và thêm hậu tố Async để thuận tiện.

Bây giờ tôi nên gọi thao tác một chiều từ ứng dụng khách như thế nào? Không sử dụng async/await ở phía bên phải cho các cuộc gọi một chiều?

Điều này có đúng không và sẽ dẫn đến xử lý không đồng bộ thực sự ở phía máy khách.

// The proxy 
    public void FinalizePublishingAsync(PageContent pageContent) 
    { 
     Channel.FinalizePublishingAsync(pageContent); 
    } 

     // The consumer of the client 
     // No way to use await for void methods. 
     IComPublisherFinalizerClient cl = new IComPublisherFinalizerClient(); 
     cl.FinalizePublishingAsync(content); 
     cl.Close(); 

Trả lời

6

Trước hết, khách hàng hoàn toàn tách biệt với máy chủ. Hoặc máy khách hoặc máy chủ có thể đồng bộ, hãy sử dụng mã không đồng bộ IAsyncResult (APM) hoặc sử dụng mã không đồng bộ async (TAP).

Thứ hai, async phương thức ở phía máy chủ phải trả lại Task, ngay cả đối với liên lạc một chiều. Phương thức đồng bộ async trả về void là phương thức async Task, không phải phương thức async void. async void đặc biệt nguy hiểm trong các dịch vụ WCF vì nó có thể vi phạm ConcurrencyMode.

Vì vậy, bước server-side của bạn sẽ trông như thế này:

  • Di OperationContract.AsyncPattern.
  • Kết hợp cặp phương thức Begin*/End* thành một phương thức *Async trả về Task.

Phía máy khách của bạn sẽ thấy Task - phương pháp gửi lại trên giao diện cho proxy của nó, cần await. Điều này không có nghĩa là bạn đang chờ phản hồi; await này cho phép bạn đợi tin nhắn thực sự được gửi (nếu có sự chậm trễ) và phát hiện lỗi truyền thông kênh (nếu bạn đang sử dụng kênh đáng tin cậy).

+0

Stephen, Cảm ơn bạn đã trả lời. Cuộc gọi một chiều không có thư trả lời và được chờ cho đến khi máy chủ nhận được yêu cầu - đây là lý do tại sao chúng được đánh dấu là khoảng trống. Nhưng như tôi biết (Juval viết về điều này) máy chủ actualy không gửi một tin nhắn trả lời ngắn nói rằng yêu cầu khách hàng được xếp hàng đợi. IAsyncResult giải quyết vấn đề này. Và bạn muốn nói rằng mặc dù các hoạt động (đánh dấu là một OneWay) trả về một nhiệm vụ người gọi sẽ không bị chặn cho đến khi trả lời của máy chủ? Hoặc nó sẽ hoạt động như một hoạt động thường xuyên OneWay chặn cho đến khi trả lời của máy chủ? – Zara

+0

Nó sẽ hoạt động như một hoạt động OneWay thông thường. Vì vậy, nó sẽ không chờ đợi cho các phương pháp máy chủ để hoàn thành (hoặc được gọi) và nó sẽ không báo cáo lỗi từ máy chủ. –

Các vấn đề liên quan