Jawaban lain di sini tampaknya mengabaikan poin terpenting:
Kecuali Anda mencoba memparalelkan operasi intensif CPU untuk menyelesaikannya lebih cepat di situs dengan beban rendah, tidak ada gunanya menggunakan thread pekerja sama sekali.
Itu berlaku untuk utas gratis, yang dibuat oleh new Thread(...)
, dan utas pekerja di ThreadPool
yang merespons QueueUserWorkItem
permintaan.
Ya, itu benar, Anda dapat membuat ThreadPool
proses ASP.NET kelaparan dengan mengantri terlalu banyak item pekerjaan. Ini akan mencegah ASP.NET memproses permintaan lebih lanjut. Informasi dalam artikel tersebut akurat dalam hal itu; kumpulan utas yang sama digunakan untuk QueueUserWorkItem
juga digunakan untuk melayani permintaan.
Tetapi jika Anda benar-benar mengantri cukup banyak item pekerjaan untuk menyebabkan kelaparan ini, maka Anda harus membuat kumpulan utas kelaparan! Jika Anda menjalankan ratusan operasi intensif CPU pada saat yang sama, apa gunanya memiliki thread pekerja lain untuk melayani permintaan ASP.NET, ketika mesin sudah kelebihan beban? Jika Anda mengalami situasi ini, Anda perlu mendesain ulang sepenuhnya!
Sebagian besar waktu saya melihat atau mendengar tentang kode multi-utas yang digunakan secara tidak tepat di ASP.NET, ini bukan untuk mengantri pekerjaan intensif CPU. Ini untuk mengantri pekerjaan terikat I / O. Dan jika Anda ingin melakukan pekerjaan I / O, maka Anda harus menggunakan thread I / O (I / O Completion Port).
Secara khusus, Anda harus menggunakan async callback yang didukung oleh kelas library apa pun yang Anda gunakan. Metode ini selalu diberi label dengan sangat jelas; mereka mulai dengan kata-kata Begin
dan End
. Seperti dalam Stream.BeginRead
, Socket.BeginConnect
, WebRequest.BeginGetResponse
, dan sebagainya.
Metode ini menggunakan ThreadPool
, tetapi mereka menggunakan IOCP, yang tidak mengganggu permintaan ASP.NET. Mereka adalah jenis benang ringan khusus yang dapat "dibangunkan" oleh sinyal interupsi dari sistem I / O. Dan dalam aplikasi ASP.NET, Anda biasanya memiliki satu utas I / O untuk setiap utas pekerja, sehingga setiap permintaan dapat memiliki satu operasi asinkron yang antri. Itu benar-benar ratusan operasi asinkron tanpa penurunan kinerja yang signifikan (dengan asumsi subsistem I / O dapat mengikutinya). Ini jauh lebih dari yang Anda butuhkan.
Perlu diingat bahwa delegasi asinkron tidak berfungsi dengan cara ini - mereka akan menggunakan thread pekerja, sama seperti ThreadPool.QueueUserWorkItem
. Hanya metode async bawaan kelas pustaka .NET Framework yang mampu melakukan ini. Anda dapat melakukannya sendiri, tetapi ini rumit dan sedikit berbahaya dan mungkin di luar cakupan diskusi ini.
Jawaban terbaik untuk pertanyaan ini, menurut saya, adalah jangan gunakan ThreadPool
atauThread
contoh latar belakang di ASP.NET . Ini sama sekali tidak seperti memutar utas dalam aplikasi Windows Forms, di mana Anda melakukannya untuk menjaga agar UI tetap responsif dan tidak peduli seberapa efisiennya itu. Di ASP.NET, perhatian Anda adalah throughput , dan semua konteks yang beralih pada semua utas pekerja tersebut benar-benar akan mematikan throughput Anda apakah Anda menggunakan ThreadPool
atau tidak.
Tolong, jika Anda menemukan diri Anda menulis kode threading di ASP.NET - pertimbangkan apakah itu dapat ditulis ulang atau tidak untuk menggunakan metode asinkron yang sudah ada sebelumnya, dan jika tidak bisa, maka pertimbangkan apakah Anda benar-benar membutuhkan kode tersebut atau tidak untuk berjalan di utas latar belakang. Dalam sebagian besar kasus, Anda mungkin akan menambahkan kompleksitas tanpa keuntungan bersih.