Andere Antworten hier scheinen den wichtigsten Punkt auszulassen:
Wenn Sie nicht versuchen, einen CPU-intensiven Vorgang zu parallelisieren, um ihn auf einer Site mit geringer Last schneller auszuführen, macht es keinen Sinn, überhaupt einen Worker-Thread zu verwenden.
Dies gilt sowohl für freie Threads, die von erstellt wurden new Thread(...)
, als auch für Arbeitsthreads ThreadPool
, die auf QueueUserWorkItem
Anforderungen reagieren .
Ja, es stimmt, Sie können das ThreadPool
in einem ASP.NET-Prozess verhungern lassen , indem Sie zu viele Arbeitselemente in die Warteschlange stellen. Dadurch wird verhindert, dass ASP.NET weitere Anforderungen verarbeitet. Die Informationen im Artikel sind in dieser Hinsicht korrekt. Der gleiche Thread-Pool, für den verwendet QueueUserWorkItem
wird, wird auch zum Bearbeiten von Anforderungen verwendet.
Aber wenn Sie tatsächlich genug Arbeitselemente in die Warteschlange stellen, um diesen Hunger zu verursachen, sollten Sie den Thread-Pool hungern lassen! Wenn Sie buchstäblich Hunderte von CPU-intensiven Vorgängen gleichzeitig ausführen, was würde es nützen, wenn ein anderer Arbeitsthread eine ASP.NET-Anforderung bedient, wenn der Computer bereits überlastet ist? Wenn Sie in diese Situation geraten, müssen Sie komplett neu gestalten!
Die meiste Zeit sehe oder höre ich, dass Multithread-Code in ASP.NET unangemessen verwendet wird. Er dient nicht dazu, CPU-intensive Arbeit in die Warteschlange zu stellen. Es dient zum Einreihen von E / A-gebundener Arbeit. Und wenn Sie E / A-Arbeiten ausführen möchten, sollten Sie einen E / A-Thread (E / A-Abschlussport) verwenden.
Insbesondere sollten Sie die asynchronen Rückrufe verwenden, die von der von Ihnen verwendeten Bibliotheksklasse unterstützt werden. Diese Methoden sind immer sehr deutlich gekennzeichnet; sie beginnen mit den Worten Begin
und End
. Wie in Stream.BeginRead
, Socket.BeginConnect
, WebRequest.BeginGetResponse
, und so weiter.
Diese Methoden machen verwenden die ThreadPool
, aber sie benutzen IOCPs, die sie nicht mit ASP.NET - Anfragen stören. Sie sind eine spezielle Art von leichtgewichtigem Thread, der durch ein Interrupt-Signal vom E / A-System "aufgeweckt" werden kann. In einer ASP.NET-Anwendung haben Sie normalerweise einen E / A-Thread für jeden Arbeitsthread, sodass für jede einzelne Anforderung eine asynchrone Operation in die Warteschlange gestellt werden kann. Das sind buchstäblich Hunderte von asynchronen Vorgängen ohne signifikante Leistungseinbußen (vorausgesetzt, das E / A-Subsystem kann mithalten). Es ist weit mehr als Sie jemals brauchen werden.
Denken Sie daran, dass asynchrone Delegaten nicht auf diese Weise funktionieren - sie verwenden am Ende genau wie einen Arbeitsthread ThreadPool.QueueUserWorkItem
. Dies können nur die integrierten asynchronen Methoden der .NET Framework-Bibliotheksklassen. Sie können es selbst tun, aber es ist kompliziert und ein bisschen gefährlich und geht wahrscheinlich über den Rahmen dieser Diskussion hinaus.
Die beste Antwort auf diese Frage ist meiner Meinung nach, dass Sie die ThreadPool
oder eine Hintergrundinstanz Thread
in ASP.NET nicht verwenden . Es ist überhaupt nicht so, als würde man einen Thread in einer Windows Forms-Anwendung hochfahren, in der Sie die Benutzeroberfläche reaktionsschnell halten und sich nicht darum kümmern, wie effizient sie ist. In ASP.NET ist Ihre Sorge Durchsatz , und alles , was Kontext auf allen diesen Arbeitsthreads Schalt absolut gehen zu töten Ihren Durchsatz , ob Sie die verwenden ThreadPool
oder nicht.
Wenn Sie Threading-Code in ASP.NET schreiben, überlegen Sie, ob er mit bereits vorhandenen asynchronen Methoden neu geschrieben werden kann. Wenn dies nicht möglich ist, prüfen Sie bitte, ob Sie den Code wirklich wirklich benötigen überhaupt in einem Hintergrund-Thread laufen. In den meisten Fällen werden Sie wahrscheinlich die Komplexität ohne Nettonutzen erhöhen.