Dalam beberapa hari terakhir saya telah menguji fitur baru .net 4.5 dan c # 5.
Saya suka fitur async / menunggu baru. Sebelumnya saya telah menggunakan BackgroundWorker untuk menangani proses yang lebih lama di latar belakang dengan UI responsif.
Pertanyaan saya adalah: setelah memiliki fitur-fitur baru yang bagus ini, kapan saya harus menggunakan async / tunggu dan kapan BackgroundWorker ? Yang merupakan skenario umum untuk keduanya?
Jawaban:
async / await dirancang untuk menggantikan konstruksi seperti
BackgroundWorker
. Meskipun Anda pasti bisa menggunakannya jika Anda mau, Anda harus dapat menggunakan async / menunggu, bersama dengan beberapa alat TPL lainnya, untuk menangani semua yang ada di luar sana.Karena keduanya berfungsi, itu tergantung pada preferensi pribadi yang Anda gunakan saat. Apa yang lebih cepat untukmu ? Apa yang lebih mudah bagi Anda untuk mengerti?
sumber
async
/await
juga memungkinkan pemrograman asinkron tanpa thread pool threads.Ini mungkin TL; DR bagi banyak orang, tetapi, saya pikir membandingkan
await
denganBackgroundWorker
seperti membandingkan apel dan jeruk dan pemikiran saya tentang hal berikut:BackgroundWorker
dimaksudkan untuk memodelkan satu tugas yang ingin Anda lakukan di latar belakang, pada utas kumpulan utas.async
/await
adalah sintaks untuk menunggu secara tidak sinkron pada operasi asinkron. Operasi-operasi itu mungkin atau mungkin tidak menggunakan thread pool thread atau bahkan menggunakan utas lainnya . Jadi, mereka adalah apel dan jeruk.Misalnya, Anda dapat melakukan sesuatu seperti berikut ini dengan
await
:Tapi, Anda mungkin tidak akan pernah memodelkan hal itu di latar belakang pekerja, Anda mungkin akan melakukan sesuatu seperti ini di .NET 4.0 (sebelum
await
):Perhatikan perbedaan pemisahan antara kedua sintaks dan bagaimana Anda tidak dapat menggunakan
using
tanpaasync
/await
.Tetapi, Anda tidak akan melakukan hal seperti itu dengan
BackgroundWorker
.BackgroundWorker
biasanya untuk memodelkan operasi jangka panjang tunggal yang Anda tidak ingin memengaruhi respons UI. Sebagai contoh:Benar-benar tidak ada di sana Anda dapat menggunakan async / tunggu,
BackgroundWorker
membuat utas untuk Anda.Sekarang, Anda bisa menggunakan TPL sebagai gantinya:
Dalam hal
TaskScheduler
ini membuat utas untuk Anda (dengan asumsi defaultTaskScheduler
), dan dapat digunakanawait
sebagai berikut:Menurut pendapat saya, perbandingan utama adalah apakah Anda melaporkan kemajuan atau tidak. Misalnya, Anda mungkin memiliki
BackgroundWorker like
ini:Tapi, Anda tidak akan berurusan dengan beberapa hal ini karena Anda akan menyeret-dan-menjatuhkan komponen pekerja latar belakang ke permukaan desain formulir - sesuatu yang tidak dapat Anda lakukan dengan
async
/await
danTask
... yaitu Anda menang ' t secara manual membuat objek, mengatur properti dan mengatur event handler. Anda hanya akan mengisi tubuhDoWork
,RunWorkerCompleted
danProgressChanged
event handler.Jika "dikonversi" menjadi async / menunggu, Anda akan melakukan sesuatu seperti:
Tanpa kemampuan untuk menyeret komponen ke permukaan Designer, terserah pembaca untuk memutuskan mana yang "lebih baik". Tapi, bagi saya, itu adalah perbandingan antara
await
danBackgroundWorker
, bukan apakah Anda bisa menunggu metode bawaan sepertiStream.ReadAsync
. mis. jika Anda menggunakanBackgroundWorker
sebagaimana dimaksud, mungkin sulit untuk mengkonversi untuk digunakanawait
.Pikiran lain: http://jeremybytes.blogspot.ca/2012/05/backgroundworker-component-im-not-dead.html
sumber
var t1 = webReq.GetResponseAsync(); var t2 = webReq2.GetResponseAsync(); await t1; await t2;
. Yang akan menunggu dua operasi paralel. Menunggu jauh lebih baik untuk tugas yang tidak sinkron, tetapi berurutan, IMO ...await Task.WhenAny(t1, t2)
untuk melakukan sesuatu ketika salah satu tugas selesai terlebih dahulu. Anda mungkin ingin perulangan untuk memastikan tugas lainnya selesai juga. Biasanya Anda ingin tahu kapan tugas tertentu selesai, yang mengarahkan Anda untuk menulis urutanawait
.Ini adalah pengantar yang bagus: http://msdn.microsoft.com/en-us/library/hh191443.aspx Bagian Threads adalah apa yang Anda cari:
sumber
BackgroundWorker secara eksplisit dilabeli sebagai usang di .NET 4.5:
Artikel MSDN "Pemrograman Asinkron dengan Async dan Menunggu (C # dan Visual Basic)" memberi tahu:
MEMPERBARUI
"untuk operasi yang terikat IO karena kodenya lebih sederhana dan Anda tidak harus waspada terhadap kondisi lomba" Kondisi lomba apa yang dapat terjadi, dapatkah Anda memberikan contoh? "
Pertanyaan ini seharusnya ditempatkan sebagai pos terpisah.
Wikipedia memiliki penjelasan yang bagus tentang kondisi balap . Bagian yang diperlukan adalah multithreading dan dari artikel MSDN yang sama Pemrograman Asinkron dengan Async dan Await (C # dan Visual Basic) :
Yaitu, "Kata kunci async dan menunggu tidak menyebabkan utas tambahan dibuat".
Sejauh yang saya ingat upaya saya ketika saya mempelajari artikel ini setahun yang lalu, jika Anda telah menjalankan dan bermain dengan sampel kode dari artikel yang sama, Anda dapat bertemu dalam situasi bahwa itu versi non-async (Anda dapat mencoba untuk mengkonversi untuk dirimu sendiri) blokir tanpa batas!
Juga, untuk contoh nyata Anda dapat mencari situs ini. Berikut ini beberapa contohnya:
sumber