2011-10-12 14 views
8

Tôi đã không có cơ hội để kiểm tra CTP của tính năng mới async/await C#, nhưng đây là điều tôi đã tự hỏi:Tính năng async/await mới trong C# 5 tích hợp với vòng lặp tin nhắn như thế nào?

Làm thế nào để nó tích hợp với vòng lặp tin nhắn? Tôi cho rằng trong một ứng dụng Windows tiêu chuẩn (Winforms, WPF), việc tiếp tục được gọi bằng cách gửi tin nhắn đến vòng lặp tin nhắn của ứng dụng, sử dụng một số Dispatcher hoặc tương tự?

Nếu tôi không sử dụng vòng lặp thông báo cửa sổ chuẩn thì sao? Ví dụ trong một ứng dụng GTK # hoặc trong một ứng dụng giao diện điều khiển (nếu thực sự tính năng này có thể được sử dụng ở tất cả trong một ứng dụng giao diện điều khiển).

Tôi đã tìm kiếm trên Internet để biết thông tin về điều này nhưng không có kết quả. Bất cứ ai có thể giải thích?

Trả lời

5

Nó sử dụng System.Threading.SynchronizationContext.Current. Cả WPF và Winforms đều cài đặt phiên bản SynchronizationContext của riêng chúng. Trong đó sử dụng vòng lặp tin nhắn của họ để sắp xếp cuộc gọi từ một chuỗi công nhân trở lại luồng giao diện người dùng chính. Tương ứng với Dispatcher.Begin/Invoke và Control.Begin/Invoke().

Thực hiện điều này trong ứng dụng chế độ Bảng điều khiển không dễ dàng, chủ đề chính của nó không có trạng thái 'nhàn rỗi' được xác định rõ ràng sẽ cho phép thực hiện các cuộc gọi marshaled một cách an toàn tránh bị đau đầu tái nhập. Bạn chắc chắn có thể thêm nó nhưng bạn sẽ tái phát minh ra vòng lặp tin nhắn làm như vậy.

+0

Cảm ơn Hank. Cố gắng nghĩ về một tình huống mà async sẽ được sử dụng trong một ứng dụng console và thất bại. Vì vậy, tôi nghĩ rằng thiếu bối cảnh đồng bộ hóa trong tình huống này chủ yếu là tranh luận. – Grokys

+3

[AsyncEx] (http://nitoasyncex.codeplex.com/) bao gồm lớp [AsyncContext] (http://nitoasyncex.codeplex.com/wikipage?title=AsyncContext) cung cấp vòng lặp chính tương thích không đồng bộ cho ứng dụng Console (và kiểm tra đơn vị). –

+0

Tìm hiểu thêm về 'SynchronizationContext' [ở đây] (http://msdn.microsoft.com/en-us/magazine/gg598924.aspx). –

4

Tất cả đều đến với những gì "chờ đợi" thực hiện với tính năng tiếp tục được truyền.

Việc triển khai Task<T> trong BCL sẽ sử dụng ngữ cảnh đồng bộ hóa hiện tại (unless you ask it not to using ConfigureAwait) - có nghĩa là trong WPF/Silverlight, nó sẽ sử dụng bộ điều phối; trong Windows Forms nó sẽ sử dụng một cái gì đó như Control.BeginInvoke, và trong một chủ đề thread-pool nó sẽ chỉ tiếp tục chạy trên bất kỳ thread thread thread. Lưu ý rằng đó là ngữ cảnh hiện tại của bạn tại thời điểm biểu thức đang chờ đợi điều quan trọng, vì đó là nhiệm vụ sẽ nắm bắt để tiếp tục chạy.

Bài đăng trên blog được liên kết (bởi Mads Torgersen) thực hiện một công việc tuyệt vời để giải thích cách hoạt động của nó dưới mui xe và tôi có một số series of blog posts mà bạn cũng có thể thấy hữu ích.

+0

Cảm ơn Jon. Trong tất cả các chuyến du ngoạn của tôi ở vùng đất .Net Tôi chưa từng gặp SynchronizationContext.Current, đó là điều tôi cho rằng ý của bạn là "bối cảnh đồng bộ hóa hiện tại"? Học điều mới mỗi ngày. – Grokys

+1

@Groky: Có. Có nhiều điều trong bài viết của Stephen Toub về hiệu suất với async: http://msdn.microsoft.com/en-us/magazine/hh456402.aspx –

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