Zeile System.Threading.ThreadPool, die zum Senden von Arbeitselementen, zum Verarbeiten asynchroner E/A, zum Warten im Namen anderer Threads und zum Verarbeiten von Timern verwendet werden kann. Grundlegende Verwendung:
public void Main() { ThreadPool.QueueUserWorkItem(JobForAThread); // 将某工作交给线程池}void JobForAThread(object state) // 线程要执行的工作:满足 委托WaitCallback {for (int i = 1; i <= 5; i++) { Console.WriteLine("Running Thread {0},Step {1}", Thread.CurrentThread.ManagedThreadId, i); Thread.Sleep(500); } }
Nach der Ausführung der Methode ThreadPool.QueueUserWorkItem() wählt der Prozessor automatisch einen Thread im Pool aus, um den „Arbeitsinhalt“ zu verarbeiten " ".
1. Wenn der Thread-Pool noch nicht läuft, wird ein Thread-Pool erstellt und der erste Thread gestartet.
2. Wenn der Thread-Pool bereits läuft und mindestens ein inaktiver Thread vorhanden ist, übergibt der Thread-Pool den „Arbeitsinhalt“ zur Verarbeitung an den inaktiven Thread.
3. Wenn zu diesem Zeitpunkt keine Leerlauf-Threads im Thread-Pool vorhanden sind, befindet sich der Job im Wartezustand, bis ein Leerlauf-Thread zur Verarbeitung vorhanden ist.
Rufen Sie die Anzahl der Thread-Pool-Anfragen ab, die gleichzeitig über die Methode ThreadPool.GetMaxThreads() aktiv sein können.
int vWorkerThreads; int vCompletionPortThreads; ThreadPool.GetMaxThreads(out vWorkerThreads, out vCompletionPortThreads); Console.WriteLine("池中辅助线程的最大数{0},池中异步 I/O 线程的最大数{1}", vWorkerThreads, vCompletionPortThreads);
Sie können die Anzahl der Thread-Pool-Anfragen festlegen, die gleichzeitig über die Methode ThreadPool.SetMaxThreads() aktiv sein können.
ThreadPool.SetMaxThreads(5, 4);
Sie können jedoch die Anzahl der sekundären Threads oder die Anzahl der asynchronen E/A-Abschlussthreads nicht auf weniger als die Anzahl der Computerprozessoren festlegen . Der Thread-Pool ist sehr einfach zu verwenden, es gibt jedoch einige Einschränkungen:
1. Alle Threads im Thread-Pool sind Hintergrund-Threads. Wenn alle Vordergrund-Threads eines Prozesses enden, werden auch alle Hintergrund-Threads gestoppt. Der in den Pool eintretende Thread kann nicht in den Vordergrund-Thread geändert werden.2. Sie können weder die Priorität noch den Namen für den Thread festlegen, der in den Pool gelangt.
3. Threads im Pool können nur für kurzfristige Aufgaben verwendet werden. Wenn der Thread ständig ausgeführt werden soll, sollten Sie die Thread-Klasse verwenden, um einen Thread zu erstellen.
Übergeben Sie den Parameter Objektstatus an die Aufgabe JobForAThread() und rufen Sie auf:
public void Main() { ThreadPool.QueueUserWorkItem(JobForAThread,"这是传递给工作内容的参数"); // 添加工作的同时,传递参数Console.ReadKey(); // 让主线程等待,否则“一闪而过” }void JobForAThread(object state) { Console.WriteLine("收到信息:{0}", (string)state); // 处理传进来的数据for (int i = 1; i <= 5; i++) { Console.WriteLine("Running Thread {0},Step {1}", Thread.CurrentThread.ManagedThreadId, i); Thread.Sleep(500); } }
Einfache Steuerungsbedienung
一Unter normalen Umständen gerät die „Arbeit“ nach der Übergabe an den Thread-Pool außer Kontrolle. Der Prozessor entscheidet automatisch, wann mit der Ausführung begonnen wird (natürlich nur, wenn inaktive Threads vorhanden sind). Mit dem folgenden Code können Sie dafür sorgen, dass der Job nach der angegebenen Zeit mit der Ausführung beginnt .
ManualResetEvent mManualEvent;public void Main() { mManualEvent = new ManualResetEvent(false); // 实例ThreadPool.QueueUserWorkItem(JobForAThread); Console.WriteLine("{0} 任务已经交给线程池了,但是它没有执行.", DateTime.Now.ToString("HH:mm:ss")); Thread.Sleep(10000); // 等待 10smManualEvent.Set(); // 发出信号,让线程继续执行 Console.ReadKey(); // 让主线程等待,否则“一闪而过” }void JobForAThread(object state) { mManualEvent.WaitOne(); // 等待 “ mManualEvent.Set();” 这一句执行(发送信号)Console.WriteLine("{0} 现在开始执行任务啦.", DateTime.Now.ToString("HH:mm:ss"));for (int i = 1; i <= 5; i++) { Console.WriteLine("Running Thread {0},Step {1}", Thread.CurrentThread.ManagedThreadId, i); Thread.Sleep(500); } }
Hier wird der Thread blockiert, nachdem die Arbeit an den Thread-Pool übergeben wurde Beim Ausführen der Arbeit wird die Arbeit im Satz mManualEvent.WaitOne(); den nachfolgenden Code erst dann weiter ausführen, wenn der Hauptthread 10 Sekunden später ein Signal sendet. Hierbei handelt es sich um einen
„Fehlstart“-Steuervorgang, der im Wesentlichen nicht zulässt, dass die angegebene Arbeit wie erwartet beginnt. Hier bedeutet der Parameter false bei der Initialisierung des ManualResetEvent-Objekts, dass das Signal standardmäßig auf den „Blockierungszustand“ gesetzt ist und das Signal durch den Code mManualEvent.Set();. Im Gegenteil, Sie können den Thread durch den Code mManualEvent.Reset(); in den „blockierten Zustand“ versetzen.
Wennvorhanden ist, müssen Sie warten, bis alle Threads im Thread-Pool die Ausführung abgeschlossen haben, bevor Sie mit der Ausführung eines anderen Codes fortfahren.
AutoResetEvent[] mAutoResetEvent;public void Main() { mAutoResetEvent = new AutoResetEvent[]{new AutoResetEvent(false), // 默认信号为 阻塞new AutoResetEvent(false),new AutoResetEvent(false) };for (int i = 0; i < 3; i++) // 创建3个工作 { Thread.Sleep(1000); ThreadPool.QueueUserWorkItem(JobForAThread, i); } Console.WriteLine("所有工作已经添加到池中..."); WaitHandle.WaitAll(mAutoResetEvent); // 等待 mAutoResetEvent 中所有信号变为 继续 后,继续后面代码Console.WriteLine("所有工作已经完成了"); Console.ReadKey(); // 让主线程等待,否则“一闪而过” }void JobForAThread(object state) {int vJobIndex = (int)state; Console.WriteLine("Job {0} Started.", vJobIndex);for (int i = 1; i <= 5; i++) { Console.WriteLine("Running Thread {0},Step {1},Job {2} ", Thread.CurrentThread.ManagedThreadId, i, vJobIndex); Thread.Sleep(500); } mAutoResetEvent[vJobIndex].Set(); }
[]
Das obige ist der detaillierte Inhalt vonC#-Multithreading – detaillierte Einführung in den Thread-Pool. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!