Maison  >  Article  >  développement back-end  >  Développement multithread C# WinForm (2) ThreadPool et Timer

Développement multithread C# WinForm (2) ThreadPool et Timer

黄舟
黄舟original
2017-02-20 10:54:151520parcourir

Adresse originale : Cliquez pour ouvrir le lien

[Résumé]Cet article présente C# ThreadPool et Timer pour le développement multithread WinForm, ainsi qu'un exemple de code détaillé sont fournis à titre de référence.

Cet article continue de ce qui précède et continue de discuter des problèmes multithread dans WinForm, en se concentrant à nouveau sur le pool de threads et le minuteur.

1. ThreadPool

Thread Pool (ThreadPool) est une méthode relativement simple qui convient aux tâches courtes qui nécessitent plusieurs threads (comme certains qui sont souvent bloqués). L'inconvénient est qu'il ne peut pas contrôler le thread créé ni définir sa priorité. Puisque chaque processus n'a qu'un seul pool de threads, et bien sûr chaque domaine d'application n'a qu'un seul pool de threads (ligne), vous constaterez que les fonctions membres de la classe ThreadPool sont toutes statiques ! Lorsque vous appelez ThreadPool.QueueUserWorkItem, ThreadPool.RegisterWaitForSingleObject, etc. pour la première fois, une instance de pool de threads sera créée. Permettez-moi de vous présenter les deux fonctions du pool de threads :


public static bool QueueUserWorkItem( //调用成功则返回true 
	    WaitCallback callBack,//要创建的线程调用的委托 
	    object state //传递给委托的参数 
	    )//它的另一个重载函数类似,只是委托不带参数而已

La fonction de cette fonction est de mettre en file d'attente les threads à créer dans le pool de threads. Lorsque le nombre de threads disponibles dans le pool de threads n'est pas nul (le pool de threads a une limite sur le nombre de threads créés et la valeur manquante est 25), ce thread sera créé, sinon il sera mis en file d'attente vers le thread. pool et attendez qu’il ait des threads disponibles.

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 
);


La fonction de cette fonction est de créer un fil d'attente une fois cela. La fonction est appelée. Ce thread est créé et il est dans un état "bloqué" jusqu'à ce que le paramètre waitObject passe à l'état terminé ou que l'heure définie TimeOut arrive. Il convient de noter que ce "bloqué" est très différent de l'état WaitSleepJoin du thread : Lorsqu'un thread est dans l'état WaitSleepJoin, le processeur le réveille régulièrement pour interroger et mettre à jour les informations d'état, puis entre à nouveau dans l'état WaitSleepJoin. La commutation de thread nécessite beaucoup de ressources, mais le thread créé avec cette fonction est différent. Avant de déclencher son exécution, le CPU ne basculera pas sur ce thread, il ne prend pas de temps CPU et ne perd pas de temps de changement de thread, mais comment le CPU sait-il quand l'exécuter ? En fait, le pool de threads générera des threads auxiliaires pour surveiller ces conditions de déclenchement. Une fois les conditions remplies, les threads correspondants seront démarrés. Bien sûr, ces threads auxiliaires eux-mêmes prennent également du temps, mais si vous devez créer plus d'attente. threads, utilisez le pool de threads. Les avantages deviennent plus évidents.

Démo plus détaillée :

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);
        } 
    }
}

Un endroit qui mérite d'être étendu, l'invocation ici utilise un proxy, en fait il existe d'autres méthodes, telles que action et func . L'exemple de code est le suivant :

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)!


Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn