元のアドレス: クリックしてリンクを開きます
[概要]この記事では C# を紹介します WinForm マルチスレッド開発用の ThreadPool と Timer、および詳細なサンプル コードが参考のために提供されています。
この記事は上記の続きで、再びスレッドプールとタイマーに焦点を当てながら、WinForm におけるマルチスレッドの問題について説明します。
ThreadPool は、複数のスレッドを必要とする短いタスク (頻繁にブロックされる一部のスレッドなど) に適しています。その欠点は、作成されたスレッドを制御できないことです。その優先順位を設定します。各プロセスにはスレッド プールが 1 つだけあり、もちろん各アプリケーション ドメインにはスレッド プール (行) が 1 つだけあるため、ThreadPool クラスのメンバー関数はすべて静的であることがわかります。 ThreadPool.QueueUserWorkItem、ThreadPool.RegisterWaitForSingleObject などを初めて呼び出すと、スレッド プール インスタンスが作成されます。スレッド プール内の 2 つの関数を紹介します。
public static bool QueueUserWorkItem( //调用成功则返回true WaitCallback callBack,//要创建的线程调用的委托 object state //传递给委托的参数 )//它的另一个重载函数类似,只是委托不带参数而已
この関数の機能は、スレッド プール内の使用可能なスレッドの数がゼロではない場合に、作成されるスレッドをスレッド プールにキューに入れることです。スレッド プールには、作成するスレッド数の制限 (デフォルト値は 25) が設定されているため、このスレッドを作成します。それ以外の場合は、スレッド プールのキューに入れられ、使用可能なスレッドが確保されるまで待機します。
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 );
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); } } }
これは価値のある拡張機能です。実際には、action や func などの他のメソッドも使用されます。コード例は次のとおりです:
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)!