C#多線程中訪問winform控件 (解決Winform 對象當前正在其他地方使用)


方法一:System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; 

不推薦使用這種方式,禁止編譯器對跨線程訪問做檢查的方式實現。

 

方法二:使用delegate和invoke

private delegate void UpdateLabel2Delegate(string message);
void UpdateLabel2(string message)
{
if (label1.InvokeRequired)
{
  UpdateLabel2Delegate md = new UpdateLabel2Delegate(UpdateLabel2);
  label1.Invoke(md, new object[] { message });
  //label1.BeginInvoke(md, new object[] { message });
}
else
{
  label1.Text = message;
}
}

 

或者:

void UpdateLabel2(string message)
{
 this.Invoke((EventHandler)delegate{ this.label1.Text = message;});
}

 

或者:(不使用委托方式,強烈推薦使用此方法)

private void button2_Click(object sender, EventArgs e)
{
Thread thread1 = new Thread(new ParameterizedThreadStart(UpdateLabel2));
thread1.Start("更新Label");
}

private void UpdateLabel2(object str)
{
if (label2.InvokeRequired)
{
// 當一個控件的InvokeRequired屬性值為真時,說明有一個創建它以外的線程想訪問它
Action<string> actionDelegate = (x) => { this.label2.Text = x.ToString(); };
// 或者
// Action<string> actionDelegate = delegate(string txt) { this.label2.Text = txt; };
this.label2.Invoke(actionDelegate, str);
}
else
{
this.label2.Text = str.ToString();
}
}

 


方法三:使用BackgroundWorker組件

 

private void button4_Click(object sender, EventArgs e)
{
using (BackgroundWorker bw = new BackgroundWorker())
{
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerAsync("Tank");
} 
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{ 
// 這里是后台線程, 是在另一個線程上完成的, 這里是真正做事的工作線程
// 可以在這里做一些費時的,復雜的操作
Thread.Sleep(5000);
e.Result = e.Argument + "工作線程完成";
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//這時后台線程已經完成,並返回了主線程,所以可以直接使用UI控件了 
this.label4.Text = e.Result.ToString(); 
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM