Saya sering melihatnya disebutkan bahwa Thread.Sleep();
tidak boleh digunakan, tetapi saya tidak dapat memahami mengapa demikian. Jika Thread.Sleep();
dapat menimbulkan masalah, apakah ada solusi alternatif dengan hasil yang sama yang aman?
misalnya.
while(true)
{
doSomework();
i++;
Thread.Sleep(5000);
}
satu lagi adalah:
while (true)
{
string[] images = Directory.GetFiles(@"C:\Dir", "*.png");
foreach (string image in images)
{
this.Invoke(() => this.Enabled = true);
pictureBox1.Image = new Bitmap(image);
Thread.Sleep(1000);
}
}
c#
multithreading
sleep
Burimi
sumber
sumber
goto:
yaitu mungkin ada solusi yang lebih baik untuk masalah Anda daripadaSleep
.goto
, yang lebih seperti bau kode daripada bau desain. Tidak ada yang salah dengan kompiler yang memasukkangoto
s ke dalam kode Anda: komputer tidak akan bingung. TapiThread.Sleep
tidak persis sama; kompiler tidak memasukkan panggilan itu dan itu memiliki konsekuensi negatif lainnya. Tapi ya, sentimen umum yang menggunakannya salah karena hampir selalu ada solusi yang lebih baik pasti benar.sleep()
kode (atau tes) anak anjing matiJawaban:
Masalah dengan memanggil
Thread.Sleep
Are menjelaskan cukup ringkas di sini :Solusi yang disukai: WaitHandles
Kesalahan yang paling banyak dibuat adalah menggunakan
Thread.Sleep
with a while-construct ( demo dan jawaban , entri blog yang bagus )EDIT:
Saya ingin meningkatkan jawaban saya:
sumber
SKENARIO 1 - menunggu tugas asinkron selesai: Saya setuju bahwa WaitHandle / Auto | ManualResetEvent harus digunakan dalam skenario di mana utas menunggu tugas di utas lain selesai.
SKENARIO 2 - timing while loop: Namun, sebagai mekanisme timing yang kasar (while + Thread.Sleep) baik-baik saja untuk 99% aplikasi yang TIDAK memerlukan pengetahuan persis kapan Thread yang diblokir harus "aktif *. Argumen yang diperlukan 200k siklus untuk membuat utas juga tidak valid - utas pengulangan waktu perlu dibuat dan siklus 200k hanyalah angka besar lainnya (beri tahu saya berapa banyak siklus untuk membuka panggilan file / socket / db?).
Jadi jika sementara + Thread.Sleep berfungsi, mengapa mempersulit? Hanya pengacara sintaksis yang praktis !
sumber
Saya ingin menjawab pertanyaan ini dari perspektif politik-pengkodean, yang mungkin berguna atau tidak bagi siapa pun. Tetapi terutama ketika Anda berurusan dengan alat yang ditujukan untuk 9-5 programmer perusahaan, orang yang menulis dokumentasi cenderung menggunakan kata-kata seperti "tidak boleh" dan "tidak pernah" berarti "jangan lakukan ini kecuali Anda benar-benar tahu apa yang Anda sedang melakukan dan mengapa ".
Beberapa favorit saya yang lain di dunia C # adalah bahwa mereka memberitahu Anda untuk "jangan pernah menelepon kunci (ini)" atau "jangan pernah menelepon GC.Collect ()". Keduanya secara paksa dideklarasikan di banyak blog dan dokumentasi resmi, dan IMO adalah informasi yang salah. Pada tingkat tertentu, informasi yang salah ini memenuhi tujuannya, yaitu menjauhkan para pemula dari melakukan hal-hal yang tidak mereka pahami sebelum sepenuhnya meneliti alternatifnya, tetapi pada saat yang sama, itu membuat sulit untuk menemukan informasi NYATA melalui mesin pencari yang semuanya tampaknya mengarah ke artikel yang memberi tahu Anda untuk tidak melakukan sesuatu sementara tidak memberikan jawaban atas pertanyaan "mengapa tidak?"
Secara politis, ini bermuara pada apa yang orang anggap sebagai "desain yang baik" atau "desain yang buruk". Dokumentasi resmi tidak boleh mendikte desain aplikasi saya. Jika benar-benar ada alasan teknis bahwa Anda tidak boleh memanggil sleep (), maka IMO dokumentasi harus menyatakan bahwa tidak apa-apa untuk memanggilnya dalam skenario tertentu, tetapi mungkin menawarkan beberapa solusi alternatif yang tidak tergantung pada skenario atau lebih sesuai untuk yang lain. skenario.
Dengan jelas menyebut "sleep ()" berguna dalam banyak situasi ketika tenggat waktu ditentukan dengan jelas dalam istilah waktu dunia nyata, namun, ada sistem yang lebih canggih untuk menunggu dan memberi sinyal utas yang harus dipertimbangkan dan dipahami sebelum Anda mulai tidur ( ) ke dalam kode Anda, dan memasukkan pernyataan sleep () yang tidak perlu dalam kode Anda umumnya dianggap sebagai taktik pemula.
sumber
Ini adalah lingkaran 1). Berputar dan 2) .polling dari contoh Anda yang harus diperhatikan orang , bukan bagian Thread.Sleep (). Saya pikir Thread.Sleep () biasanya ditambahkan untuk dengan mudah meningkatkan kode yang berputar atau dalam loop polling, jadi ini hanya terkait dengan kode "buruk".
Selain itu, orang melakukan hal-hal seperti:
di mana variabel inWait tidak diakses dengan cara yang aman untuk thread, yang juga menyebabkan masalah.
Yang ingin dilihat pemrogram adalah utas yang dikontrol oleh konstruksi Peristiwa dan Pemberian Sinyal dan Penguncian, dan ketika Anda melakukannya, Anda tidak perlu Thread.Sleep (), dan kekhawatiran tentang akses variabel aman-thread juga dihilangkan. Sebagai contoh, dapatkah Anda membuat penangan peristiwa yang terkait dengan kelas FileSystemWatcher dan menggunakan peristiwa untuk memicu contoh ke-2 alih-alih perulangan?
Seperti yang disebutkan Andreas N., membaca Threading dalam C #, oleh Joe Albahari , benar-benar bagus.
sumber
Thread.Sleep()
dengan fungsi lain, dan memanggilnya di loop sementara?Sleep digunakan dalam kasus di mana program independen yang tidak dapat Anda kendalikan terkadang menggunakan resource yang umum digunakan (misalnya, file), yang perlu diakses oleh program Anda saat berjalan, dan saat resource digunakan oleh program tersebut. program lain program Anda diblokir dari menggunakannya. Dalam kasus ini, di mana Anda mengakses sumber daya dalam kode Anda, Anda meletakkan akses sumber daya dalam coba-tangkap (untuk menangkap pengecualian ketika Anda tidak dapat mengakses sumber daya), dan Anda meletakkannya di loop sementara. Jika sumber daya gratis, sleep tidak akan pernah dipanggil. Namun jika sumber daya diblokir, Anda akan tidur selama jangka waktu yang sesuai, dan mencoba mengakses sumber daya lagi (inilah alasan Anda melakukan perulangan). Namun, perlu diingat bahwa Anda harus meletakkan semacam pembatas pada loop, jadi ini bukan loop yang berpotensi tak terbatas.
sumber
Saya memiliki kasus penggunaan yang tidak terlalu saya lihat di sini, dan akan berpendapat bahwa ini adalah alasan yang valid untuk menggunakan Thread.Sleep ():
Dalam aplikasi konsol yang menjalankan pekerjaan pembersihan, saya perlu melakukan sejumlah besar panggilan database yang cukup mahal, ke DB yang dibagikan oleh ribuan pengguna bersamaan. Agar tidak memalu DB dan mengecualikan orang lain selama berjam-jam, saya perlu jeda antar panggilan, dalam urutan 100 ms. Ini tidak terkait dengan waktu, hanya untuk memberikan akses ke DB untuk utas lainnya.
Menghabiskan 2000-8000 siklus pada peralihan konteks antar panggilan yang mungkin memerlukan 500 md untuk dieksekusi tidaklah berbahaya, seperti halnya memiliki 1 MB tumpukan untuk utas, yang berjalan sebagai satu contoh di server.
sumber
Thread.Sleep
aplikasi Konsol satu utas dan tujuan tunggal seperti yang Anda jelaskan tidak masalah.Saya setuju dengan banyak hal di sini, tetapi saya juga berpikir itu tergantung.
Baru-baru ini saya melakukan kode ini:
Itu adalah fungsi animasi sederhana, dan saya menggunakannya
Thread.Sleep
.Kesimpulan saya, jika itu berhasil, gunakanlah.
sumber
Bagi Anda yang belum melihat satu pun argumen valid yang menentang penggunaan Thread.Sleep di SKENARIO 2, sebenarnya ada satu - keluar aplikasi ditahan oleh while loop (SKENARIO 1/3 hanya bodoh jadi tidak layak untuk lebih menyebutkan)
Banyak yang berpura-pura menjadi tahu, berteriak Thread.Sleep is evil gagal menyebutkan satu alasan yang sah bagi kita yang menuntut alasan praktis untuk tidak menggunakannya - tapi ini dia, terima kasih kepada Pete - Thread.Sleep itu Jahat (dapat dengan mudah dihindari dengan timer / handler)
sumber
Thread.Sleep
bukan alasan untuk ini (utas baru merupakan loop sementara yang berkelanjutan)! Anda dapat menghapusThread.Sleep
-line - et voila: program tidak akan keluar juga ...