程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#完成窗體與子線程的交互的辦法

C#完成窗體與子線程的交互的辦法

編輯:C#入門知識

C#完成窗體與子線程的交互的辦法。本站提示廣大學習愛好者:(C#完成窗體與子線程的交互的辦法)文章只能為提供參考,不一定能成為您想要的結果。以下是C#完成窗體與子線程的交互的辦法正文


本文實例簡述了C#完成窗體與子線程間通信的辦法,關於C#初學者有必定的自創價值。詳細辦法以下:

普通來講窗體上的UI在默許情形下不許可應用子線程(或許其它非創立控件的UI線程)去掌握(這在NET2.0以下是許可的,然則斟酌到平安性等成績,從2.0開端就制止應用這個功效,除非Form的CheckForIllegalCrossThreadCalls=true,不推舉如許應用)。

那末若何完成C#窗體與子線程的交互呢?詳細辦法以下:

1、應用Invoke或許BeginInvoke辦法:

用一個線程,裡邊挪用Invoke或許BeginInvoke辦法便可:

public partial class Form1 : Form
{
public void Processing(int num)
{
int answer = 2;
Task t = new Task(() =>
{
for (int i = 3; i <= num; i++)
{
answer *= i;
}
this.BeginInvoke(new MethodInvoker(() => { Thread.Sleep(3000); MessageBox.Show("Finished!") }));
MessageBox.Show("OK");
});
t.Start();
}
public Form1()
{
InitializeComponent();

}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("First!");
Processing(10);
}
}

這裡值得留意:
1)BeginInvoke:這裡的“異步”其實不是針對UI線程,而是說當Control的BeginInvoke在某個子線程中挪用時,子線程中BeginInvoke前面的代碼(彈出“Finished”框框)會先履行,然後比及BeginInvoke中的誰人拜托辦法完整履行終了以後Label才會被賦值。假如改成Invoke,那末“OK”永久在Invoke的拜托代碼完全履行終了以後才被履行。
所以BeginInvoke=Invoke(在UI主線程中,所以不建議在主線程中直接如許挪用)

2、線程同步SynchronizedContext:

public partial class Form1 : Form
{
public void Processing(int num,SynchronizationContext context)
{
int answer = 2;
Task t = new Task(() =>
{
for (int i = 3; i <= num; i++)
{
answer *= i;
}
SynchronizationContext.SetSynchronizationContext(context);
SynchronizationContext.Current.Post((obj) => { Thread.Sleep(3000); MessageBox.Show("Finished"); }, null);
MessageBox.Show("Last");
});
t.Start();
}
public Form1()
{
InitializeComponent();

}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("First!");
Processing(10,SynchronizationContext.Current);
}
}

和BeginInvoke、Invoke相似,須要留意:

1)SynchronizationContext:惟獨在UI窗體線程中會主動初始化(button1_Click事宜中SynchronizationContext.Current為以後窗體),其它線程與線程要交互,必需經由過程new SynchronizationContext()完成)。
2)Post辦法同等於BeginInvoke感化,Send同等於Invoke感化。

年夜家假如細心試驗代碼,還會發明不管何種情形,彈出“Finished”框框老是界面“假逝世”3秒,是的,證實了以上4個辦法都是在UI線程上履行的(只不外是同步或許異步向窗體新聞泵發送信息罷了)。所以應當“一次性地把數據在子線程中先全體處置清潔(在Invoke,BeginInvoke,Send或許Post前得出成果,寫代碼),然後一次性發送告訴給窗體,更新界面便可)。

另外還須要留意:

任何拜托(Delegate)也有BeginInvoke辦法,它是真實的異步,一旦Invoke必定是開拓一個線程去履行的。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved