Bagaimana cara mendapatkan Thread.Sleep yang menunggu?

149

Saya sedang menulis aplikasi terikat jaringan berdasarkan paradigma menunggu / tidur.

Terkadang, kesalahan koneksi terjadi, dan menurut pengalaman saya, sebaiknya menunggu beberapa saat dan kemudian mencoba kembali operasi.

Masalahnya adalah jika saya menggunakan Thread.Sleep atau operasi pemblokiran serupa lainnya di await / async, ini akan memblokir semua aktivitas di thread pemanggil.

Dengan apa saya harus mengganti Thread.Sleep (10000) untuk mendapatkan efek yang sama seperti

await Thread.SleepAsync(10000)

?

MEMPERBARUI

Saya lebih suka jawaban yang melakukan ini tanpa membuat utas tambahan

Arsen Zahray
sumber

Jawaban:

342

Jawaban lain yang menyarankan memulai utas baru adalah ide yang buruk - tidak perlu melakukan itu sama sekali. Bagian dari tujuan async/ awaitadalah mengurangi jumlah utas yang dibutuhkan aplikasi Anda.

Anda sebaiknya menggunakan Task.Delayyang tidak memerlukan utas baru, dan dirancang dengan tepat untuk tujuan ini:

// Execution of the async method will continue one second later, but without
// blocking.
await Task.Delay(1000);
Jon Skeet
sumber
Saya masih memahami hal-hal a4.5. Di mana cabang eksekusi pada kode setelah pernyataan itu? Apakah bagian non-tidur / pemblokiran menjalankannya atau 'utas' yang menunggu? Apakah eksekusi non-pemblokiran utama hanya meninggalkan blok berikut (alias kembali)?
kenny
1
ya. Inilah PERSIS yang saya butuhkan
Arsen Zahray
1
@kenny: Anda mungkin merasa asyncpengantar saya bermanfaat. Ketika awaitable dikembalikan oleh Task.Delayyang awaited, karena itu tidak lengkap, metode saat mengembalikan sebuah tugas yang tidak lengkap. Nanti, ketika Delayselesai (off timer, bukan thread), sisa metode dijadwalkan untuk dijalankan. Kelanjutan berjalan dalam "konteks" yang dapat kembali ke utas asli yang sama - detail di blog saya.
Stephen Cleary
@StephenCleary terima kasih untuk itu. Jadi, apakah saya benar mengatakan bahwa kode setelah menunggu 'dijadwalkan' untuk dieksekusi dan utas panggilan kembali?
kenny
2
Ya, utas panggilan kembali (segera) dan kode setelah awaitdijadwalkan (akhirnya).
Stephen Cleary