Apakah Task.Delay benar-benar asinkron seperti operasi I / O, yaitu apakah ini bergantung pada perangkat keras dan interupsi, bukan pada utas?
Saya telah menemukan banyak konten terkait yang bertele-tele dan saya tidak pernah dapat menemukan jawabannya. Saya hampir 100% yakin bahwa Task.Delay(int)
tidak menggunakan utas, karena saya dapat menjalankan kode ini di mesin saya hanya dengan 16 prosesor logis:
var tasks = new List<Task>();
for(int i = 1; i < 100000; i++) tasks.Add(Task.Delay(10000));
await Task.WhenAll(tasks);
Dan butuh sepuluh detik untuk menyelesaikannya. Jika itu menggunakan kira-kira seratus ribu utas, itu akan memakan waktu lebih lama, saya pikir.
Jadi pertanyaan saya adalah bagaimana cara Task.Delay(int)
kerjanya? Bukan dengan cara yang ditunjukkan oleh pertanyaan SO dengan judul yang buruk ini , tetapi dari sudut pandang threading dan sumber daya perangkat keras.
Jawaban
Dalam implementasi .NET saat ini, ada satu "utas pengatur waktu" yang hanya melacak kejadian pengatur waktu yang dikelola dan memunculkan kejadiannya pada waktu yang tepat. Utas pengatur waktu ini akan memblokir sinyal kontrolnya dengan batas waktu disetel ke waktu tenggat waktu berikutnya. Sinyal kontrol digunakan untuk menambah / menghapus / mengubah pengatur waktu, jadi ketika permintaan pemblokiran ini habis waktu, utas pengatur waktu mengetahui pengatur waktu berikutnya telah diaktifkan. Ini adalah operasi pemblokiran utas normal, jadi secara internal, utas dimatikan dan dihapus dari antrean penjadwal hingga operasi pemblokiran itu selesai atau habis waktunya. Waktu keluar dari operasi tersebut ditangani oleh penghitung waktu penjadwal OS.
Jadi secara teknis ada utas, tetapi hanya satu utas per proses, bukan satu utas per Task.Delay
.
Saya sekali lagi menekankan bahwa ini dalam implementasi saat ini .NET. Solusi lain telah diusulkan, seperti satu thread timer per CPU, atau kumpulan thread timer dinamis. Mungkin mereka telah diujicobakan dan ditolak karena alasan tertentu, atau mungkin solusi alternatif akan diadopsi di masa depan. AFAIK ini tidak didokumentasikan secara resmi di mana pun, jadi ini adalah detail implementasi.