Apakah ada aturan yang baik untuk kapan menggunakan Task.Delay versus Thread.Tidur ?
- Secara khusus, adakah nilai minimum untuk menyediakan agar satu menjadi efektif / efisien di atas yang lain?
- Terakhir, karena Task.Delay menyebabkan pengalihan konteks pada mesin status async / wait, apakah ada overhead untuk menggunakannya?
Jawaban:
Gunakan
Thread.Sleep
saat Anda ingin memblokir utas saat ini.Gunakan
Task.Delay
saat Anda menginginkan penundaan logis tanpa memblokir utas saat ini.Efisiensi seharusnya tidak menjadi perhatian utama dengan metode ini. Penggunaan dunia nyata utama mereka adalah sebagai coba lagi timer untuk operasi I / O, yang berada di urutan detik daripada milidetik.
sumber
Thread.Sleep
akan memblokir utas saat ini yang menyebabkan sakelar konteks. Jika Anda menggunakan kumpulan utas, ini juga dapat menyebabkan utas baru dialokasikan. Kedua operasi cukup berat sedangkan koperasi multi-tugas yang disediakan olehTask.Delay
dll dirancang untuk menghindari semua overhead itu, memaksimalkan throughput, memungkinkan pembatalan, dan menyediakan kode yang lebih bersih.onesi: I would use
Thread.Sleep` untuk menunggu di dalam metode sinkron. Namun, saya tidak pernah melakukan ini dalam kode produksi; dalam pengalaman saya, setiap yangThread.Sleep
pernah saya lihat menunjukkan masalah desain yang perlu diperbaiki dengan benar.Perbedaan terbesar antara
Task.Delay
danThread.Sleep
adalah yangTask.Delay
dimaksudkan untuk berjalan secara tidak sinkron. Tidak masuk akal untuk menggunakanTask.Delay
kode sinkron. Ini adalah ide yang SANGAT buruk untuk digunakanThread.Sleep
dalam kode asinkron.Biasanya Anda akan menelepon
Task.Delay()
denganawait
kata kunci:atau, jika Anda ingin menjalankan beberapa kode sebelum penundaan:
Coba tebak ini akan mencetak? Berjalan selama 0,0070048 detik. Jika kita memindahkan yang di
await delay
atasConsole.WriteLine
, itu akan mencetak Running selama 5.0020168 detik.Mari kita lihat perbedaannya dengan
Thread.Sleep
:Coba tebak apa yang akan dicetak ini ...
Juga, menarik untuk diperhatikan bahwa
Thread.Sleep
jauh lebih akurat, akurasi ms tidak benar-benar masalah, sementaraTask.Delay
dapat mengambil minimal 15-30ms. Overhead pada kedua fungsi minimal dibandingkan dengan akurasi ms yang dimilikinya (gunakanStopwatch
Kelas jika Anda membutuhkan sesuatu yang lebih akurat).Thread.Sleep
masih mengikat Thread Anda,Task.Delay
lepaskan untuk melakukan pekerjaan lain saat Anda menunggu.sumber
Thread.Sleep()
mengkonsumsi seluruh utas yang seharusnya dapat digunakan di tempat lain. Jika banyak tugas dijalankan dengan Thread.Sleep (), ada kemungkinan besar melelahkan semua utas threadpool dan secara serius menghambat kinerja.async
metode karena mereka didorong untuk digunakan. Ini pada dasarnya hanya ide buruk untuk dijalankanThread.Sleep()
di utas threadpool, bukan ide buruk pada umumnya. Lagi pula, adaTaskCreationOptions.LongRunning
saat pergi rute (meskipun berkecil hati)Task.Factory.StartNew()
.await wait
Tasl.Delay
menggunakan timer sistem. Karena "Jam sistem" terus-menerus "pada laju yang konstan.", Kecepatan tick dari timer sistem adalah sekitar 16 ms, setiap penundaan yang Anda minta akan dibulatkan ke sejumlah tick dari jam sistem, diimbangi dengan waktu hingga yang pertama kutu. Lihat dokumentasiTask.Delay
msdn di docs.microsoft.com/en-us/dotnet/api/… dan gulir ke bawah untuk komentar.jika utas saat ini terbunuh dan Anda gunakan
Thread.Sleep
dan sedang dieksekusi maka Anda mungkin mendapatkanThreadAbortException
. DenganTask.Delay
Anda selalu dapat memberikan token pembatalan dan dengan anggun membunuhnya. Itulah salah satu alasan saya akan memilihTask.Delay
. lihat http://social.technet.microsoft.com/wiki/contents/articles/21177.visual-c-thread-sleep-vs-task-delay.aspxSaya juga setuju efisiensi bukan yang terpenting dalam kasus ini.
sumber
await Task.Delay(5000)
. Ketika saya membunuh tugas yang saya dapatkanTaskCanceledException
(dan menekannya) tetapi utas saya masih hidup. Rapi! :)Saya ingin menambahkan sesuatu. Sebenarnya,
Task.Delay
mekanisme menunggu berbasis timer. Jika Anda melihat sumbernya, Anda akan menemukan referensi keTimer
kelas yang bertanggung jawab atas keterlambatan tersebut. Di sisi lainThread.Sleep
sebenarnya membuat utas saat ini tertidur, dengan cara itu Anda hanya memblokir dan membuang satu utas. Dalam model pemrograman async Anda harus selalu menggunakanTask.Delay()
jika Anda menginginkan sesuatu (kelanjutan) terjadi setelah beberapa penundaan.sumber