2012-06-30 25 views
19

Điểm khác biệt thực sự giữa Mô hình lập trình không đồng bộMẫu không đồng bộ dựa trên sự kiện là gì?lập trình không đồng bộ APM vs EAP

Phương pháp sử dụng và thời điểm nào?

+2

Các [MSDN docs] (http: //msdn.microsoft.com/en-us/library/jj152938.aspx) bao gồm điều này khá tốt. –

+0

Bài viết tuyệt vời! Chắc chắn được thêm vào bộ sưu tập dấu trang của tôi. – Erik

Trả lời

17

Các Asynchronous Programming Mẫu (APM) là mô hình mà bạn nhìn thấy với BeginMethod(...)EndMethod(...) cặp.

Ví dụ ở đây là một Socket sử dụng APM thực hiện:

var socket = new Socket(AddressFamily.InterNetwork, 
         SocketType.Stream, ProtocolType.Tcp); 

// ... 

socket.BeginReceive(recvBuffer, 0, recvBuffer.Length, 
        SocketFlags.None, ReceiveCallback, null); 

void ReceiveCallback(IAsyncResult result) 
{ 
    var bytesReceived = socket.EndReceive(result); 

    if (bytesReceived > 0) { // Handle received data here. } 

    if (socket.Connected) 
    { 
    // Keep receiving more data... 
    socket.BeginReceive(recvBuffer, 0, recvBuffer.Length, 
         SocketFlags.None, ReceiveCallback, null); 
    } 
} 

Các dựa Event-Asynchronous Pattern (EAP) là mô hình mà bạn nhìn thấy với MethodAsync(...)CancelAsync(...) cặp. Thường có sự kiện Completed. BackgroundWorker là một ví dụ điển hình cho mẫu này.

Tính đến C# 4.5, cả hai đã được thay thế bởi mô hình async/await, được sử dụng công tác song song Thư viện (TPL). Bạn sẽ thấy chúng được đánh dấu bằng Async sau tên phương thức và thường trả lại awaitableTask hoặc Task<TResult>. Nếu bạn có thể nhắm mục tiêu .NET 4.5, bạn chắc chắn nên sử dụng mẫu này trên thiết kế APM hoặc EAP.

Ví dụ, nén một (khả năng lớn) nộp không đồng bộ:

public static async Task CompressFileAsync(string inputFile, string outputFile) 
{ 
    using (var inputStream = File.Open(inputFile, FileMode.Open, FileAccess.Read)) 
    using (var outputStream = File.Create(outputFile)) 
    using (var deflateStream = new DeflateStream(outputStream, CompressionMode.Compress)) 
    { 
    await inputStream.CopyToAsync(deflateStream); 

    deflateStream.Close(); 
    outputStream.Close(); 
    inputStream.Close(); 
    } 
} 
5

Từ mã khách hàng POV:

EAP: Bạn thiết lập một trình xử lý sự kiện cho một sự kiện có tên kết thúc bằng "Đã hoàn thành "sau đó gọi một phương thức có tên kết thúc bằng" Async ". Đôi khi bạn có thể gọi phương thức có "Hủy" trong tên có thể hủy phương thức đó.

APM: Bạn gọi phương thức có tên bắt đầu bằng "Bắt đầu" rồi thăm dò kết quả hoặc nhận lại cuộc gọi, sau đó gọi phương thức bắt đầu bằng "Kết thúc".

Theo như tôi biết về hai, APM được triển khai trên hầu hết các lớp BCL IO và WCF, chủ yếu là các hoạt động không thể xử lý cấp thấp hơn (như hủy bỏ bạn chỉ bỏ qua kết quả). EAP được tìm thấy trên các lớp cấp cao hơn, tức là tải xuống tệp, trong đó có nhiều bước và một số hành vi hủy có ý nghĩa.

Vì vậy, nếu bạn cần chọn cách triển khai (và bạn đang cố tình hạn chế bản thân cho hai điều này), tôi đoán việc bạn đang làm là có thể hủy hay không.

Từ mã khách hàng POV, bạn không phải lúc nào cũng có lựa chọn. Tốt nhất có thể là sử dụng các nhiệm vụ C# 4.5 nếu bạn có thể, chúng có thể làm việc với bất kỳ cơ chế async cũ nào thông qua trình bao bọc.

+2

Điểm tốt về việc thiếu chức năng hủy bỏ trên thiết kế __APM__. Cũng như đã đề cập, 'Task.Factory.FromAsync (...)' là trình bao bọc C# 4.5 để chuyển kiểu __APM__ thành mẫu __TPL__. Xem: Erik

+0

Xin lỗi, đang tranh luận với SO ý kiến ​​ở đây (tại sao hầu hết định dạng liên kết "được hỗ trợ" của họ __NOT__ hoạt động trong nhận xét)? [Lập trình không đồng bộ .NET và TPL truyền thống] (http://msdn.microsoft.com/en-us/library/dd997423.aspx) – Erik

2

Câu trả lời toàn diện được đưa ra tại bài viết MSDN "Deciding When to Implement the Event-based Asynchronous Pattern".

Ý tưởng chính của bài viết này (và trả lời ngắn gọn cho câu hỏi của bạn) âm thanh như "Tạo mô hình dựa trên sự kiện theo mặc định, với một tùy chọn để tạo ra các mô hình IAsyncResult"

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