Buradaki diğer cevaplar en önemli noktayı dışarıda bırakıyor gibi görünüyor:
Düşük yüklü bir sitede daha hızlı halletmek için CPU yoğun bir işlemi paralelleştirmeye çalışmadığınız sürece, bir işçi iş parçacığı kullanmanın hiçbir anlamı yoktur.
Bu, hem tarafından oluşturulan ücretsiz iş parçacıkları hem de isteklere yanıt veren new Thread(...)
çalışan iş parçacıkları ThreadPool
için geçerlidir QueueUserWorkItem
.
Evet, doğru, çok fazla iş öğesini kuyruğa alarak bir ASP.NET sürecini aç bırakabilirsinizThreadPool
. ASP.NET'in başka istekleri işlemesini engelleyecektir. Makaledeki bilgiler bu bakımdan doğrudur; için kullanılan aynı iş parçacığı havuzu QueueUserWorkItem
, isteklere hizmet etmek için de kullanılır.
Ancak, bu açlığa neden olacak kadar iş öğesini gerçekten sıraya koyuyorsanız, iş parçacığı havuzunu aç bırakmalısınız ! Kelimenin tam anlamıyla yüzlerce CPU yoğun işlemi aynı anda çalıştırıyorsanız, makine zaten aşırı yüklendiğinde bir ASP.NET isteğine hizmet edecek başka bir çalışan iş parçacığına sahip olmanın ne faydası olur? Bu durumla karşılaşırsanız, tamamen yeniden tasarlamanız gerekir!
Çoğu zaman çok iş parçacıklı kodun ASP.NET'te uygunsuz bir şekilde kullanıldığını görüyorum veya duyuyorum, bu CPU yoğun çalışmayı kuyruğa almak için değil. G / Ç bağlantılı işi sıraya koymak için. Ve G / Ç çalışması yapmak istiyorsanız, bir G / Ç iş parçacığı (G / Ç Tamamlama Bağlantı Noktası) kullanmalısınız.
Özellikle, kullandığınız kütüphane sınıfı tarafından desteklenen zaman uyumsuz geri aramaları kullanıyor olmalısınız. Bu yöntemler her zaman çok açık bir şekilde etiketlenmiştir; onlar sözlerle başlar Begin
ve End
. Olduğu gibi Stream.BeginRead
, Socket.BeginConnect
, WebRequest.BeginGetResponse
, vb.
Bu yöntemler yapmak kullanmak ThreadPool
, ancak do IOCPs kullanmak değil ASP.NET istekleri ile müdahale. G / Ç sisteminden gelen bir kesinti sinyaliyle "uyandırılabilen" özel bir hafif iplik türüdür. Ve bir ASP.NET uygulamasında, normalde her çalışan iş parçacığı için bir G / Ç iş parçacığına sahip olursunuz, bu nedenle her bir istekte sıraya alınmış bir zaman uyumsuz işlem olabilir. Bu, herhangi bir önemli performans düşüşü olmaksızın kelimenin tam anlamıyla yüzlerce eşzamansız işlemdir (G / Ç alt sisteminin devam edebileceğini varsayarsak). İhtiyacınız olandan çok daha fazla.
Eşzamansız delegelerin bu şekilde çalışmadığını unutmayın - tıpkı bir işçi iş parçacığı kullanacaklar ThreadPool.QueueUserWorkItem
. Bunu yapabilen yalnızca .NET Framework kitaplık sınıflarının yerleşik zaman uyumsuz yöntemleridir. Bunu kendiniz yapabilirsiniz, ancak bu karmaşık ve biraz tehlikelidir ve muhtemelen bu tartışmanın kapsamı dışındadır.
Kanımca bu sorunun en iyi yanıtı ASP.NET'te veya arka plan örneğini kullanmamaktırThreadPool
Thread
. Bu, bir Windows Forms uygulamasında, kullanıcı arayüzünü duyarlı tutmak için yaptığınız ve ne kadar verimli olduğunu umursamadığınız bir iş parçacığı açmak gibi değil. ASP.NET'te, endişeniz aktarım hızıdır ve tüm bu çalışan iş parçacıkları üzerindeki tüm bu bağlam geçişleri, .NET Framework'ü kullansanız da kullanmasanız da aktarım hızınızı kesinlikle öldürecektirThreadPool
.
Lütfen, kendinizi ASP.NET'te iş parçacığı kodu yazarken bulursanız - önceden var olan eşzamansız yöntemleri kullanmak için yeniden yazılıp yazılamayacağını düşünün ve yapamazsa, lütfen koda gerçekten, gerçekten ihtiyacınız olup olmadığını düşünün bir arka plan iş parçacığında çalıştırmak için. Çoğu durumda, muhtemelen net bir fayda sağlamadan karmaşıklık katacaksınız.