2011-11-09 39 views
8

Tôi đang triển khai dịch vụ không đồng bộ. Sau khi đánh giá example của Microsoft, tôi tự hỏi liệu cách tiếp cận của họ có thực sự không đồng bộ hay không. Tôi khá chắc chắn nó là, nhưng một số mẫu tôi đã nhìn thấy trực tuyến và tham số AsyncCallback làm cho tôi tự hỏi.Dịch vụ WCF không đồng bộ thực sự

Theo ví dụ này, chúng ta cần phải thực hiện các BeginEnd phương pháp cặp như thế này:

public IAsyncResult BeginGetAcmeAnvil(AsyncCallback callback, object state) 
{ 
    // Starts synchronous task 
    var acmeAsyncResult = new AcmeAsyncResult<Anvil> 
    { 
    Data = new Anvil() 
    };  
    return acmeAsyncResult; 
} 

public Anvil EndGetAcmeAnvil(IAsyncResult result) 
{ 
    var acmeAsyncResult = result as AcmeAsyncResult<Anvil>; 

    return acmeAsyncResult != null 
    ? acmeAsyncResult.Data 
    : new Anvil(); 
} 

Khá đơn giản, nhưng tại sao chúng ta có một tham số AsyncCallback? Chúng ta có nên thực hiện cuộc gọi đến callback để kích hoạt phương thức Kết thúc không?

Đây là những gì tôi có trong tâm trí:

public delegate void AsyncMethodCaller(AcmeAsyncResult<Anvil> acmeAsyncResult, 
             AsyncCallback callback); 

public IAsyncResult BeginGetAcmeAnvil(AsyncCallback callback, object state) 
{ 
    var acmeAsyncResult = new AcmeAsyncResult<Anvil>(); 
    var asyncMethodCaller = new AsyncMethodCaller(GetAnvilAsync); 

    // Starts asynchronous task 
    asyncMethodCaller.BeginInvoke(acmeAsyncResult, callback, null, null); 

    return acmeAsyncResult; 
} 

private void GetAcmeAnvilAsync(AcmeAsyncResult<Anvil> acmeAsyncResult, 
           AsyncCallback callback) 
{ 
    acmeAsyncResult.Data = new Anvil(); 
    callback(acmeAsyncResult); // Triggers EndGetAcmeAnvil 
} 

public Anvil EndGetAcmeAnvil(IAsyncResult result) 
{ 
    var acmeAsyncResult = result as AcmeAsyncResult<Anvil>; 

    return acmeAsyncResult != null 
    ? acmeAsyncResult.Data 
    : new Anvil(); 
} 

tôi đã làm một số thử tải bằng loadUI, nhưng không có thay đổi hiệu suất rõ ràng.

Trả lời

5

Tôi đã tìm thấy một số good article giải thích cách nhận hiệu suất tốt nhất từ ​​dịch vụ WCF Async của bạn.

Các ý chính là:

  1. không làm công việc nặng nhọc trong Begin phương pháp, và
  2. làm làm cho callback để kích hoạt End phương pháp.

Dưới đây là một chiết xuất từ ​​các văn bản:

Đối với hiệu suất tốt nhất, sau đây là hai nguyên tắc khi bạn gọi/thực hiện mô hình không đồng bộ trên:

  • Nguyên tắc 1: Không thực hiện công việc nặng nhọc bên trong phương thức Bắt đầu ...

    Lý do cho điều này là bạn nên trả lại chuỗi cuộc gọi càng sớm càng tốt để người gọi có thể lên lịch công việc khác. Nếu đó là một chuỗi giao diện người dùng, ứng dụng cần sử dụng chuỗi này để trả lời các đầu vào của người dùng. Bạn nên luôn đặt các hoạt động nặng trong một luồng khác nếu có thể.

  • Nguyên tắc 2: Tránh gọi End phương pháp trên cùng một sợi của Begin phương pháp.

    Phương thức Kết thúc thường chặn. Nó chờ thao tác hoàn thành. Nếu bạn triển khai phương thức Kết thúc, bạn sẽ thấy rằng nó thực sự gọi IAsyncResult.WaitHandle.WaitOne(). Mặt khác, để thực hiện bình thường, WaitHandle này là sự chậm trễ được phân bổ Hướng dẫn sử dụngResetEvent. Chừng nào bạn không gọi nó, nó sẽ không được phân bổ chút nào. Đối với hoạt động nhanh, điều này khá rẻ. Tuy nhiên, sau khi gọi Kết thúc được gọi, bạn sẽ phải phân bổ nó. Đúng nơi để gọi Kết thúc là từ gọi lại của hoạt động. Khi gọi lại gọi, điều đó có nghĩa là công việc chặn thực sự đã hoàn thành. Tại thời điểm này, bạn có thể gọi Kết thúc để nhận dữ liệu mà không bị mất hiệu suất.

2

Tôi nghĩ rằng lý do chính của nó tách ra như thế này là thời gian chạy WCF là xử lý đồng bộ hóa thread như trái ngược với bạn phải xử lý nó bằng tay.

Nếu bạn gọi phương thức kết thúc thông qua gọi lại, bạn sẽ phải xử lý việc đồng bộ hóa làm cho mẫu phức tạp hơn một chút (như bạn có thể thấy trong ví dụ mã hóa của mình). Mục tiêu của mô hình này không phải là để bạn thực sự nhận thức được những thứ luồng, bạn chỉ muốn mã hoạt động lâu dài của bạn mà không cần phải suy nghĩ về các chi tiết thực hiện của luồng.

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