QueueUserWorkItem方法将非常简单的任务排入队列
下面这个简单的代码,涉及到资源竞争问题,如果主线程先争取到资源,如果没有等待
一段时间,那么QueueUserWorkItem申请的线程没有机会执行。
1 using System; 2 using System.Threading; 3 4 public static void Main() 5 { 6 // Queue the task. 7 ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc)); 8 9 Console.WriteLine("Main thread does some work, then sleeps."); 10 // If you comment out the Sleep, the main thread exits before 11 // the thread pool task runs. The thread pool uses background 12 // threads, which do not keep the application running. (This 13 // is a simple example of a race condition.) 14 Thread.Sleep(1000); 15 16 Console.WriteLine("Main thread exits."); 17 } 18 19 // This thread procedure performs the task. 20 static void ThreadProc(Object stateInfo) 21 { 22 // No state object was passed to QueueUserWorkItem, so 23 // stateInfo is null. 24 Console.WriteLine("Hello from the thread pool."); 25 } 26
下面的代码示例使用 QueueUserWorkItem 方法将任务排入队列,并为该任务提供数据。
1 using System; 2 using System.Threading; 3 4 // TaskInfo holds state information for a task that will be 5 // executed by a ThreadPool thread. 6 public class TaskInfo 7 { 8 // State information for the task. These members 9 // can be implemented as read-only properties, read/write 10 // properties with validation, and so on, as required. 11 public string Boilerplate; 12 public int Value; 13 14 // Public constructor provides an easy way to supply all 15 // the information needed for the task. 16 public TaskInfo(string text, int number) 17 { 18 Boilerplate = text; 19 Value = number; 20 } 21 } 22 23 public class Example 24 { 25 public static void Main() 26 { 27 // Create an object containing the information needed 28 // for the task. 29 TaskInfo ti = new TaskInfo("This report displays the number {0}.", 42); 30 31 // Queue the task and data. 32 if (ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadProc), ti)) 33 { 34 Console.WriteLine("Main thread does some work, then sleeps."); 35 36 // If you comment out the Sleep, the main thread exits before 37 // the ThreadPool task has a chance to run. ThreadPool uses 38 // background threads, which do not keep the application 39 // running. (This is a simple example of a race condition.) 40 Thread.Sleep(1000); 41 42 Console.WriteLine("Main thread exits."); 43 } 44 else 45 { 46 Console.WriteLine("Unable to queue ThreadPool request."); 47 } 48 } 49 50 // The thread procedure performs the independent task, in this case 51 // formatting and printing a very simple report. 52 // 53 static void ThreadProc(Object stateInfo) 54 { 55 TaskInfo ti = (TaskInfo)stateInfo; 56 Console.WriteLine(ti.Boilerplate, ti.Value); 57 } 58 } 59
使用 RegisterWaitForSingleObject
下面的示例展示多种线程处理功能。
- 使用 RegisterWaitForSingleObject 方法,将任务排入队列,以便由 ThreadPool 线程执行。
- 使用 AutoResetEvent 发出要执行的任务的信号。 请参阅 EventWaitHandle, AutoResetEvent, CountdownEvent, ManualResetEvent。
- 使用 WaitOrTimerCallback 委托处理超时和信号。
- 使用 RegisteredWaitHandle 取消排队的任务。
注意:
在Main方法的最后有一句:
If you start a thread yourself, you can wait for it to end by calling Thread.Join. This option is not available with thread pool threads.
1 using System; 2 using System.Threading; 3 4 // TaskInfo contains data that will be passed to the callback 5 // method. 6 public class TaskInfo 7 { 8 public RegisteredWaitHandle Handle = null; 9 public string OtherInfo = "default"; 10 } 11 12 public class Example 13 { 14 public static void Main(string[] args) 15 { 16 // The main thread uses AutoResetEvent to signal the 17 // registered wait handle, which executes the callback 18 // method. 19 AutoResetEvent ev = new AutoResetEvent(false); 20 21 TaskInfo ti = new TaskInfo(); 22 ti.OtherInfo = "First task"; 23 // The TaskInfo for the task includes the registered wait 24 // handle returned by RegisterWaitForSingleObject. This 25 // allows the wait to be terminated when the object has 26 // been signaled once (see WaitProc). 27 ti.Handle = ThreadPool.RegisterWaitForSingleObject( 28 ev, 29 new WaitOrTimerCallback(WaitProc), 30 ti, 31 1000, 32 false); 33 34 // The main thread waits three seconds, to demonstrate the 35 // time-outs on the queued thread, and then signals. 36 Thread.Sleep(3100); 37 Console.WriteLine("Main thread signals."); 38 ev.Set(); 39 40 // The main thread sleeps, which should give the callback 41 // method time to execute. If you comment out this line, the 42 // program usually ends before the ThreadPool thread can execute. 43 Thread.Sleep(1000); 44 // If you start a thread yourself, you can wait for it to end 45 // by calling Thread.Join. This option is not available with 46 // thread pool threads. 47 } 48 49 // The callback method executes when the registered wait times out, 50 // or when the WaitHandle (in this case AutoResetEvent) is signaled. 51 // WaitProc unregisters the WaitHandle the first time the event is 52 // signaled. 53 public static void WaitProc(object state, bool timedOut) 54 { 55 // The state object must be cast to the correct type, because the 56 // signature of the WaitOrTimerCallback delegate specifies type 57 // Object. 58 TaskInfo ti = (TaskInfo)state; 59 60 string cause = "TIMED OUT"; 61 if (!timedOut) 62 { 63 cause = "SIGNALED"; 64 // If the callback method executes because the WaitHandle is 65 // signaled, stop future execution of the callback method 66 // by unregistering the WaitHandle. 67 if (ti.Handle != null) 68 ti.Handle.Unregister(null); 69 } 70 71 Console.WriteLine("WaitProc( {0} ) executes on thread {1}; cause = {2}.", 72 ti.OtherInfo, 73 Thread.CurrentThread.GetHashCode().ToString(), 74 cause 75 ); 76 } 77 } 78
时间: 2024-10-07 08:13:59