Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Erläuterung des Unterschieds zwischen C# Invoke und BeginInvoke

Detaillierte Erläuterung des Unterschieds zwischen C# Invoke und BeginInvoke

零下一度
零下一度Original
2017-06-28 15:38:211777Durchsuche

Öffnet die BeginInvoke-Methode wirklich einen neuen Thread für asynchrone Aufrufe?

Beziehen Sie sich auf den folgenden Code:

public delegate void treeinvoke();private void UpdateTreeView()
{
MessageBox.Show(System.Threading.Thread.CurrentThread.Name );
}private void button1_Click(object sender, System.EventArgs e)
{
System.Threading.Thread.CurrentThread.Name = "UIThread";
treeView1.BeginInvoke(new treeinvoke(UpdateTreeView )) ;
}

Sehen Sie sich die laufenden Ergebnisse an. Das Popup-Dialogfeld zeigt UIThread an, das zeigt, dass der von BeginInvoke aufgerufene Delegat grundsätzlich im UI-Thread ausgeführt wird.

Da es im UI-Thread ausgeführt wird, wie kann es als „asynchrone Ausführung“ bezeichnet werden?

Schauen wir uns noch einmal den folgenden Code an:

public delegate void treeinvoke();private void UpdateTreeView()
{
MessageBox.Show(Thread.CurrentThread.Name);
}private void button1_Click(object sender, System.EventArgs e)
{
Thread.CurrentThread.Name = "UIThread";
Thread th = new Thread(new ThreadStart(StartThread));
th.Start();
}private void StartThread()
{
Thread.CurrentThread.Name = "Work Thread";
treeView1.BeginInvoke(new treeinvoke(UpdateTreeView));
}

Sehen Sie sich die laufenden Ergebnisse noch einmal an. Im Popup-Dialogfeld wird weiterhin UIThread angezeigt. Dies zeigt, dass der von der BeginInvoke-Methode aufgerufene Delegat ohnehin im UI-Thread ausgeführt wird.

Was nützt BeginInvoke dann?

Bei der Multithread-Programmierung müssen wir häufig die Schnittstellenanzeige im Arbeitsthread aktualisieren, und es ist falsch, die Schnittstellensteuerung in Multithreads direkt aufzurufen. Die spezifischen Gründe finden Sie in meinem Artikel Nachher Lesen Sie den Artikel: So rufen Sie Winform in Multithreads auf. Wenn Sie ein Experte sind, lesen Sie diesen Artikel nicht.

Invoke und BeginInvoke scheinen dieses Problem zu lösen, sodass Sie die Schnittstellenanzeige in Multithreads sicher aktualisieren können.

Der richtige Ansatz besteht darin, den an der Aktualisierung der Schnittstelle im Arbeitsthread beteiligten Code in eine Methode zu kapseln und ihn über Invoke oder BeginInvoke aufzurufen. Der Unterschied zwischen den beiden besteht darin, dass einer den Arbeitsthread warten lässt der andere nicht.

Das sogenannte „Reagieren auf Vorgänge beim Hinzufügen von Knoten“ kann nur relativ sein, damit die Belastung des UI-Threads nicht zu groß wird, da die korrekte Aktualisierung der Schnittstelle immer über erfolgen muss Wir müssen die meisten Berechnungen im Arbeitsthread übernehmen und reine Schnittstellenaktualisierungen in den UI-Thread einfügen, um so den Zweck zu erreichen, die Belastung des UI-Threads zu verringern.

Im Code, der den Baumknoten aktualisiert, ist der einzige Code, der tatsächlich funktioniert: System.Threading.Thread.Sleep(100);, der dem UI-Thread die Möglichkeit gibt, Schnittstellennachrichten zu verarbeiten. Digital Ghost verkompliziert das Problem, solange der folgende Code gut funktioniert.

private void button1_Click_(object sender, System.EventArgs e)
{
TreeNode tn; for(int i=0;i<100000;i++)
{
tn= new TreeNode (i.ToString()); this.treeView1.Nodes[0].Nodes.Add(tn); if (i%100 == 0) Application.DoEvents();
}
}

Das obige ist der detaillierte Inhalt vonDetaillierte Erläuterung des Unterschieds zwischen C# Invoke und BeginInvoke. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

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