Heim  >  Artikel  >  Backend-Entwicklung  >  C# WinForm Multithread-Entwicklung (2) ThreadPool und Timer

C# WinForm Multithread-Entwicklung (2) ThreadPool und Timer

黄舟
黄舟Original
2017-02-20 10:54:151465Durchsuche

Ursprüngliche Adresse: Klicken Sie hier, um den Link zu öffnen

[Zusammenfassung]Dieser Artikel stellt C# vor ThreadPool und Timer für die WinForm-Multithread-Entwicklung sowie detaillierter Beispielcode werden als Referenz bereitgestellt.

Dieser Artikel setzt das oben Gesagte fort und bespricht weiterhin Multithreading-Probleme in WinForm, wobei der Schwerpunkt erneut auf Threadpool und Timer liegt.

1. ThreadPool (ThreadPool) ist eine relativ einfache Methode. Sie eignet sich für kurze Aufgaben, die mehrere Threads erfordern (z. B. einige, die häufig blockiert werden). Der Nachteil besteht darin, dass es weder den erstellten Thread steuern noch seine Priorität festlegen kann. Da jeder Prozess nur einen Thread-Pool hat und natürlich jede Anwendungsdomäne nur einen Thread-Pool (Zeile) hat, werden Sie feststellen, dass die Mitgliedsfunktionen der ThreadPool-Klasse alle statisch sind! Wenn Sie ThreadPool.QueueUserWorkItem, ThreadPool.RegisterWaitForSingleObject usw. zum ersten Mal aufrufen, wird eine Thread-Pool-Instanz erstellt. Lassen Sie mich die beiden Funktionen im Thread-Pool vorstellen:


public static bool QueueUserWorkItem( //调用成功则返回true 
	    WaitCallback callBack,//要创建的线程调用的委托 
	    object state //传递给委托的参数 
	    )//它的另一个重载函数类似,只是委托不带参数而已
Die Funktion dieser Funktion besteht darin, die zu erstellenden Threads in die Warteschlange des Thread-Pools zu stellen. Wenn die Anzahl der verfügbaren Threads im Thread-Pool nicht Null ist (die Anzahl der erstellten Threads ist im Thread-Pool begrenzt und der fehlende Wert beträgt 25), wird dieser Thread erstellt. Andernfalls wird er in die Warteschlange gestellt Pool und warten Sie, bis Threads verfügbar sind.


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


Die Funktion dieser Funktion besteht darin, einen wartenden Thread zu erstellen Die Funktion wird aufgerufen. Dieser Thread wird erstellt und befindet sich in einem „blockierten“ Zustand, bis der Parameter waitObject in den beendeten Zustand wechselt oder die festgelegte Zeit TimeOut erreicht. Es ist erwähnenswert, dass sich dieser „blockierte“ Zustand stark vom WaitSleepJoin-Status des Threads unterscheidet: Wenn sich ein Thread im WaitSleepJoin-Status befindet, wird er regelmäßig von der CPU aktiviert, um die Statusinformationen abzufragen und erneut in den WaitSleepJoin-Status zu wechseln. Der mit dieser Funktion erstellte Thread ist jedoch sehr ressourcenintensiv. Bevor die Ausführung ausgelöst wird, wechselt die CPU nicht zu diesem Thread. Dies nimmt weder CPU-Zeit in Anspruch, noch verschwendet es Zeit für den Thread-Wechsel. Aber woher weiß die CPU, wann sie ausgeführt werden muss? Tatsächlich generiert der Thread-Pool einige Hilfsthreads, um diese Auslösebedingungen zu überwachen. Sobald die Bedingungen erfüllt sind, nehmen diese Hilfsthreads selbst natürlich auch Zeit in Anspruch, aber wenn Sie mehr Wartezeiten benötigen Threads, verwenden Sie den Thread-Pool. Die Vorteile werden deutlicher.

Detailliertere 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);
        } 
    }
}
Ein Ort, der es wert ist, erweitert zu werden. Der Aufruf hier verwendet einen Proxy. Tatsächlich gibt es andere Methoden wie action und func . Der Beispielcode lautet wie folgt:

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


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn