C# WinFormマルチスレッド開発(2) ThreadPoolとTimer

黄舟
リリース: 2017-02-20 10:54:15
オリジナル
1523 人が閲覧しました

元のアドレス: クリックしてリンクを開きます

[概要]この記事では C# を紹介します WinForm マルチスレッド開発用の ThreadPool と Timer、および詳細なサンプル コードが参考のために提供されています。

この記事は上記の続きで、再びスレッドプールとタイマーに焦点を当てながら、WinForm におけるマルチスレッドの問題について説明します。

1. ThreadPool

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 
);
ログイン後にコピー


この関数の機能は、待機中のスレッドを作成することです。この関数が呼び出されると、このスレッドはパラメータ waitObject が終了状態または設定に変わるまで待機します。 「ブロッキング」状態では、この「ブロッキング」がスレッドの WaitSleepJoin 状態とは大きく異なることに注意してください。スレッドが WaitSleepJoin 状態にある場合、CPU は更新されたものをポーリングするために定期的にスレッドを起動します。ステータス情報を取得してから再度 WaitSleepJoin ステータスを入力すると、スレッドの切り替えは非常にリソースを消費します。この関数で作成されたスレッドは、実行をトリガーする前にこのスレッドに切り替わりません。スレッドの切り替え時間ですが、CPU はどのようにしてスレッドを実行するタイミングを知るのでしょうか?実際、スレッド プールはこれらのトリガー条件を監視するためにいくつかの補助スレッドを生成します。もちろん、条件が満たされると、これらの補助スレッド自体も開始されますが、さらに待機を作成する必要がある場合には実行されます。スレッドの場合は、スレッド プールを使用します。利点はさらに明白になります。

より詳細なデモ:

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;
    }
}
ログイン後にコピー

二、 Timer


它适用于需周期性调用的方法,它不在创建计时器的线程中运行,它在由系统自动分配的单独线程中运行。这和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)!


関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート