Pertanyaan Apakah Async menunggu kata kunci yang setara dengan lambda ContinueWith?


Bisakah seseorang harap berbaik hati untuk mengonfirmasi apakah saya telah memahami kata kunci menunggu Async dengan benar? (Menggunakan versi 3 dari CTP)

Sejauh ini saya telah bekerja bahwa memasukkan kata kunci menunggu sebelum panggilan metode pada dasarnya melakukan 2 hal, A. Ini menciptakan pengembalian segera dan B. Ini menciptakan "kelanjutan" yang dipanggil setelah selesainya doa metode async. Dalam hal apapun, kelanjutannya adalah sisa blok kode untuk metode ini.

Jadi apa yang saya ingin tahu adalah, apakah dua bit kode ini secara teknis setara, dan jika demikian, apakah ini pada dasarnya berarti bahwa kata kunci menunggu identik dengan menciptakan Lamba ContinueWith (Ie: yang pada dasarnya merupakan kompilator pintas untuk satu)? Jika tidak, apa perbedaannya?

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"));

76
2018-01-07 03:53


asal


Jawaban:


Gagasan umum benar - sisa metode ini dibuat menjadi semacam lanjutan.

Itu Pos blog "jalur cepat" memiliki detail tentang bagaimana async/await transformasi kompilator bekerja.

Perbedaan, di luar kepala saya:

Itu await kata kunci juga menggunakan konsep "konteks penjadwalan". Konteks penjadwalan adalah SynchronizationContext.Current jika ada, jatuh kembali TaskScheduler.Current. Kelanjutan ini kemudian dijalankan pada konteks penjadwalan. Jadi pendekatan yang lebih dekat akan berlalu TaskScheduler.FromCurrentSynchronizationContext ke ContinueWith, jatuh kembali TaskScheduler.Current jika diperlukan.

Sebenarnya async/await implementasi didasarkan pada pencocokan pola; ia menggunakan pola "menunggu" yang memungkinkan hal lain selain tugas yang harus ditunggu. Beberapa contoh adalah WinRT asynchronous APIs, beberapa metode khusus seperti Yield, Rx dapat diobservasi, dan socket awaitables khusus yang tidak memukul GC dengan keras. Tugasnya sangat kuat, tetapi mereka bukan satu-satunya yang menunggu.

Satu lagi perbedaan kecil rewel muncul di benak: jika yang sudah ditunggu sudah selesai, maka async metode tidak benar-benar kembali pada titik itu; itu terus serentak. Jadi itu seperti melintas TaskContinuationOptions.ExecuteSynchronously, tetapi tanpa masalah terkait tumpukan.


76
2018-01-07 04:39



Ini "pada dasarnya" itu, tetapi kode yang dihasilkan tidak ketat lebih dari itu. Untuk lebih banyak detail pada kode yang dihasilkan, saya sangat merekomendasikan seri Eduasync Jon Skeet:

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

Secara khusus, pos # 7 mendapatkan apa yang dihasilkan (seperti dari CTP 2) dan mengapa, jadi mungkin sangat cocok untuk apa yang Anda cari saat ini:

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

EDIT: Saya pikir ini mungkin lebih detail daripada yang Anda cari dari pertanyaan, tetapi jika Anda bertanya-tanya apa yang terlihat seperti ketika Anda memiliki beberapa menunggu dalam metode, yang tercakup dalam posting # 9 :)

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


8
2018-01-07 04:38