2012-01-07 26 views
74

Có thể ai đó vui lòng xác nhận xem tôi có hiểu từ khóa Async đang chờ chính xác không? (Sử dụng phiên bản 3 của CTP)Là Async đang chờ từ khóa tương đương với một ContinueWith lambda?

Vì vậy, đến nay tôi đã tìm ra rằng chèn từ khóa chờ đợi trước một cuộc gọi phương thức về cơ bản là 2 điều, A. Nó tạo ra lợi tức ngay lập tức và B. Nó tạo ra một "sự tiếp tục" được gọi khi hoàn thành lời gọi phương thức async. Trong mọi trường hợp, việc tiếp tục là phần còn lại của khối mã cho phương thức. Vì vậy, điều tôi đang phân vân là hai bit mã tương đương về mặt kỹ thuật, và nếu vậy, điều này về cơ bản có nghĩa là từ khóa chờ đợi giống hệt nhau để tạo ra một ContinueWith Lambda (Tức là: nó là một trình biên dịch cơ bản cho một) ? Nếu không, sự khác biệt là gì?

bool Success = 
    await new POP3Connector(
     "mail.server.com", txtUsername.Text, txtPassword.Text).Connect(); 
// At this point the method will return and following code will 
// only be invoked when the operation is complete(?) 
MessageBox.Show(Success ? "Logged In" : "Wrong password"); 

VS

(new POP3Connector(
    "mail.server.com", txtUsername.Text, txtPassword.Text).Connect()) 
.ContinueWith((success) => 
    MessageBox.Show(success.Result ? "Logged In" : "Wrong password")); 

Trả lời

73

Ý tưởng chung là đúng - thời gian còn lại của phương pháp này được lập thành một sự tiếp nối của các loại.

"fast path" blog post có chi tiết về cách hoạt động của quá trình chuyển đổi trình biên dịch async/await.

khác biệt, ra khỏi đỉnh đầu của tôi:

Từ khóa await cũng làm cho việc sử dụng một "bối cảnh lịch" khái niệm. Ngữ cảnh lập lịch là SynchronizationContext.Current nếu nó tồn tại, rơi trở lại trên TaskScheduler.Current. Tiếp tục sau đó chạy trên ngữ cảnh lập lịch biểu. Vì vậy, gần đúng hơn là để vượt qua TaskScheduler.FromCurrentSynchronizationContext vào ContinueWith, giảm trở lại trên TaskScheduler.Current nếu cần.

Thực tế async/await triển khai dựa trên mẫu phù hợp; nó sử dụng một mẫu "awaitable" cho phép những thứ khác ngoài các nhiệm vụ được chờ đợi. Một số ví dụ là các API không đồng bộ của WinRT, một số phương pháp đặc biệt như Yield, các quan sát Rx và special socket awaitables that don't hit the GC as hard. Nhiệm vụ rất mạnh mẽ, nhưng chúng không phải là thứ duy nhất chờ đợi.

Một sự khác biệt nhỏ về nitpicky là: nếu việc chờ đợi đã hoàn tất, thì phương thức async không thực sự trở lại vào thời điểm đó; nó tiếp tục đồng bộ. Vì vậy, nó giống như đi qua TaskContinuationOptions.ExecuteSynchronously, nhưng không có các vấn đề liên quan đến ngăn xếp.

+2

rất hay nói - Tôi cố gắng trì hoãn các bài đăng của Jon vì chúng rộng hơn nhiều so với bất cứ điều gì tôi có thời gian để trả lời về SO, nhưng Stephen hoàn toàn đúng. WRT những gì đang chờ đợi (và GetAwaiter nói riêng), bài đăng của anh ấy # 3 rất hữu ích IMHO :) http://msmvps.com/blogs/jon_skeet/archive/2011/05/13/eduasync-part-3-the-shape- of-the-async-method-awaitable-boundary.aspx –

+4

Điểm của Stephen ở đây. Đối với các ví dụ đơn giản, thật dễ dàng để nghĩ rằng async/await chỉ là một phím tắt cho ContinueWith - tuy nhiên, tôi thích nghĩ về nó ngược lại. Async/await thực sự là một biểu hiện mạnh mẽ hơn về những gì bạn sử dụng để sử dụng ContinueWith cho. Vấn đề là ContinueWith (...) sử dụng lambdas, và cho phép thực hiện để được chuyển sang tiếp tục, nhưng các khái niệm luồng điều khiển khác như vòng lặp là không thể nếu bạn phải đặt một nửa của vòng lặp trước ContinueWith (.. .) và nửa kia sau. Bạn kết thúc với chuỗi liên tục thủ công. –

+7

Một ví dụ khác khi không đồng bộ/chờ đợi diễn đạt hơn nhiều so với ContinueWith (...) đang chảy ngoại lệ. Bạn có thể chờ đợi nhiều lần trong cùng một khối thử và cho mỗi giai đoạn thực hiện, ngoại lệ của chúng có thể được chuyển vào cùng một khối catch (...) mà không cần phải viết tấn mã làm điều đó một cách rõ ràng. –

8

Đó là "cơ bản" đó, nhưng các mã được tạo không đúng hơn đó. Đối với các lô chi tiết hơn về các mã được tạo, tôi rất muốn khuyên bạn nên loạt Eduasync Jon Skeet:

http://codeblog.jonskeet.uk/category/eduasync/

Đặc biệt, bài # 7 được vào những gì được tạo ra (như của CTP 2) và tại sao, như vậy có lẽ rất phù hợp cho những gì bạn đang tìm kiếm vào lúc này:

http://codeblog.jonskeet.uk/2011/05/20/eduasync-part-7-generated-code-from-a-simple-async-method/

EDIT: tôi nghĩ rằng nó có khả năng được chi tiết hơn so với những gì bạn đang tìm kiếm từ các câu hỏi, nhưng nếu bạn đang băn khoăn những gì trông giống như khi bạn có nhiều đang chờ đợi trong phương pháp, đó là bao gồm trong bài # 9 :)

http://codeblog.jonskeet.uk/2011/05/30/eduasync-part-9-generated-code-for-multiple-awaits/

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