Інші відповіді тут, здається, не залишають найважливішого моменту:
Якщо ви не намагаєтеся паралелізувати операційну процесору оперативну роботу, щоб зробити її швидше на сайті з низьким навантаженням, немає сенсу використовувати робочу нитку взагалі.
Це стосується як вільних потоків, створених new Thread(...)
, так і робочих потоків у ThreadPool
відповіді на QueueUserWorkItem
запити.
Так, це правда, ви можете поголодувати ThreadPool
процесом ASP.NET, поставивши в чергу занадто багато елементів роботи. Це не дозволить ASP.NET обробляти подальші запити. Інформація у статті в цьому відношенні є точною; той самий пул потоків, який використовується QueueUserWorkItem
, також використовується для обслуговування запитів.
Але якщо ви насправді в черзі вистачаєте робочих предметів, щоб викликати це голодування, то вам слід голодувати пулом ниток! Якщо ви одночасно виконуєте сотні операційних процесорів, яка користь буде мати ще один робочий потік для обслуговування запиту ASP.NET, коли машина вже перевантажена? Якщо ви стикаєтеся з цією ситуацією, вам потрібно повністю переробити дизайн!
Більшу частину часу я бачу або чую про те, що багатопотоковий код неправильно використовується в ASP.NET, це не для чергової роботи з процесором. Він призначений для черги роботи, пов'язаної з входом / виводом. І якщо ви хочете виконувати роботу вводу / виводу, тоді вам слід використовувати потік вводу / виводу (порт завершення вводу / виводу).
Зокрема, ви повинні використовувати зворотні дзвінки async, підтримувані будь-яким класом бібліотеки, який ви використовуєте. Ці методи завжди дуже чітко марковані; вони починаються зі слів Begin
і End
. Як і в Stream.BeginRead
, Socket.BeginConnect
, WebRequest.BeginGetResponse
, і так далі.
Ці методи роблять використовувати ThreadPool
, але вони використовують IOCPs, у яких НЕ втручаються запитів ASP.NET. Вони являють собою особливий вид легкої нитки, який може бути "пробуджений" сигналом переривання від системи вводу / виводу. І в додатку ASP.NET у вас зазвичай є один потік вводу / виводу для кожного робочого потоку, тому кожен запит може мати одну чергу з асинхронною чергою. Це буквально сотні операцій асинхронізації без істотного зниження продуктивності (якщо припустити, що підсистема вводу / виводу може йти в ногу). Це набагато більше, ніж вам коли-небудь знадобиться.
Пам’ятайте лише про те, що делегати асинхронізу не працюють таким чином - вони в кінцевому підсумку використовують робочу нитку, як і раніше ThreadPool.QueueUserWorkItem
. Це робити здатні лише вбудовані методи асинхрування класів бібліотеки .NET Framework. Можна зробити це самостійно, але це складно і трохи небезпечно і, ймовірно, виходить за рамки цієї дискусії.
Найкращою відповіддю на це питання, на мою думку, є не використання екземпляра ThreadPool
або фонового Thread
екземпляра в ASP.NET . Це зовсім не так, як закручувати нитку в додатку Windows Forms, де ви це робите, щоб інтерфейс інтерфейсу відповідав і не хвилювався, наскільки він ефективний. В ASP.NET ваша проблема полягає в пропускній спроможності , і все те, що контекстне перемикання всіх цих робочих потоків абсолютно знищує вашу пропускну здатність, використовуєте ви ThreadPool
чи ні.
Будь ласка, якщо ви виявите, що ви пишете код для нарізки в ASP.NET - подумайте, чи можна його переписати для використання попередньо існуючих асинхронних методів, а якщо це не вдається, то, будь ласка, подумайте, чи справді вам потрібен справді код? взагалі працювати у фоновому потоці. У більшості випадків, ймовірно, ви додасте складності без чистої вигоди.