Home > Article > Backend Development > C# WinForm multi-thread development (2) ThreadPool and Timer
Original address: Click to open the link
[Abstract]This article introduces C# ThreadPool and Timer for WinForm multi-thread development, and detailed sample code is provided for reference.
This article continues from the above and continues to discuss multi-threading issues in WinForm, focusing again on threadpool and timer.
Thread Pool (ThreadPool) is a relatively simple method. It is suitable for short tasks that require multiple threads (such as some that are often blocked). Thread), its disadvantage is that it cannot control the created thread, nor can it set its priority. Since each process has only one thread pool, and of course each application domain has only one thread pool (line), you will find that the member functions of the ThreadPool class are all static! When you call ThreadPool.QueueUserWorkItem, ThreadPool.RegisterWaitForSingleObject, etc. for the first time, a thread pool instance will be created. Let me introduce the two functions in the thread pool:
public static bool QueueUserWorkItem( //调用成功则返回true WaitCallback callBack,//要创建的线程调用的委托 object state //传递给委托的参数 )//它的另一个重载函数类似,只是委托不带参数而已
The function of this function is to queue the threads to be created into the thread pool. When the thread pool When the number of available threads is not zero (the thread pool has a limit on the number of threads created, and the missing value is 25), this thread will be created. Otherwise, it will be queued to the thread pool and wait until it has available threads.
public static RegisteredWaitHandle RegisterWaitForSingleObject( WaitHandle waitObject,// 要注册的 WaitHandle WaitOrTimerCallback callBack,// 线程调用的委托 object state,//传递给委托的参数 int TimeOut,//超时,单位为毫秒, bool executeOnlyOnce //是否只执行一次 ); public delegate void WaitOrTimerCallback( object state,//也即传递给委托的参数 bool timedOut//true表示由于超时调用,反之则因为waitObject );
The function of this function is to create a waiting thread, which is created once this function is called This thread is in a "blocked" state until the parameter waitObject changes to the terminated state or the set time TimeOut arrives. It is worth noting that this "blocked" state is very different from Thread's WaitSleepJoin state: when a certain When the Thread is in the WaitSleepJoin state, the CPU will wake it up regularly to poll and update the status information, and then enter the WaitSleepJoin state again. Thread switching is very resource-intensive; but the thread created with this function is different. Before triggering it to run, the CPU Will not switch to this thread, it neither takes up CPU time nor wastes thread switching time, but how does the CPU know when to run it? In fact, the thread pool will generate some auxiliary threads to monitor these trigger conditions. Once the conditions are met, the corresponding threads will be started. Of course, these auxiliary threads themselves also take up time, but if you need to create more waiting threads, use the thread pool's The advantages become more obvious.
More detailed content demo:
namespace TestMethodInvoker { public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //ThreadPool.RegisterWaitForSingleObject( // ev, // new WaitOrTimerCallback(WaitThreadFunc), // 4, // 2000, // false//表示每次完成等待操作后都重置计时器,直到注销等待 // ); ThreadPool.QueueUserWorkItem(new WaitCallback(ThreadFunc), "test1"); //Thread.Sleep(10000); } private delegate void MyInvokeDelegate(string name); private void Test(object o) { richTextBox1.Text += string.Format("the object is {0} \n", o); } public void ThreadFunc(object b) { this.Invoke(new MyInvokeDelegate(Test), b); } public void WaitThreadFunc(object b, bool t) { richTextBox1.Text += string.Format("the object is {0},t is {1}\n", b, t); } } }
It is a place worth expanding. The invoke here uses a proxy. In fact, there are other methods, such as action and func. The example code is as follows:
this.Invoke(new Action<string>(this.ChangeText), o.ToString()); this.Invoke(new Action(delegate() { this.textBox1.Text = o.ToString();})); private void DoSomething(object o) { System.Func<string, int> f = new Func<string, int>(this.GetId); object result = this.Invoke(f, o.ToString()); MessageBox.Show(result.ToString()); } private int GetId(string name) { this.textBox1.Text = name; if (name == "Y") { return 999; } else { return 0; } }
它适用于需周期性调用的方法,它不在创建计时器的线程中运行,它在由系统自动分配的单独线程中运行。这和Win32中的SetTimer方法类似。它的构造为:
public Timer( TimerCallback callback,//所需调用的方法 object state,//传递给callback的参数 int dueTime,//多久后开始调用callback int period//调用此方法的时间间隔 );//
如果 dueTime 为0,则 callback 立即执行它的首次调用。如果 dueTime 为 Infinite,则 callback 不调用它的方法。计时器被禁用,但使用 Change 方法可以重新启用它。如果 period 为0或 Infinite,并且 dueTime 不为 Infinite,则 callback 调用它的方法一次。计时器的定期行为被禁用,但使用 Change 方法可以重新启用它。如果 period 为零 (0) 或 Infinite,并且 dueTime 不为 Infinite,则 callback 调用它的方法一次。计时器的定期行为被禁用,但使用 Change 方法可以重新启用它。
在创建计时器之后若想改变它的period和dueTime,我们可以通过调用Timer的Change方法来改变:
public bool Change( int dueTime, int period );//
显然所改变的两个参数对应于Timer中的两参数。
以上就是C# WinForm多线程开发(二) ThreadPool 与 Timer的内容,更多相关内容请关注PHP中文网(www.php.cn)!