c線程訪問控制項
1. c# 多線程 新開子線程中暫停,調用主線程式控制制項,如何防止UI阻塞
1.新開的線程是無法直接訪問UI控制項的,如果需要訪問,可以通過控制項的Invoke方法,或者用
System.Threading.SynchronizationContext.Current.Post方法
2.一定不要在控制項的內部事件處理方法裡面使用Sleep等線程暫停方法!
像我這樣寫就不會阻塞了:
private void button1_Click(object sender, EventArgs e){System.Threading.Thread thread = new System.Threading.Thread(() ={while (true){this.Invoke(new Action(() ={label1.Text = (count++).ToString();}));System.Threading.Thread.Sleep(100);}});thread.IsBackground = true;
thread.Start();}你把setmess這個線程方法Invoke到了UI的主線程上了,而這個線程裡面有暫停方法,所以呢主線程也會暫停卡住。
而我的方法只是把「label1.Text = (count++).ToString();」Invoke到主線程,而那個新的線程並沒有Invoke到主線程,所以在那個線程裡面使用暫停就沒事了!
假如有一個操作比較費時,或者需要等待之類的,就像我這樣開始一個新的線程,所以的等待操作,費時的操作都在在這個線程裡面做,當這些線程需要訪問UI控制項的時候,就用this.Invoke()這個方法!
2. C# 子線程訪問主窗體控制項
是的,
在其他線程里,不允許調用主線程創建的控制項~!!!!
這樣做,是不安全的,因此,2.0屏蔽了這個~
樓上說的很對,用委託,具體代碼如下~:
public delegate void MyInvoke(string str);
private void button9_Click(object sender, EventArgs e)
{
//_myInvoke = new MyInvoke(SetText);
// = false;
Thread t = new Thread(new ThreadStart(fun));
t.Start();
}
private void fun()
{
//_myInvoke("dddd");
SetText("ddd");
}
private void SetText(string s)
{
if (textBox6.InvokeRequired)
{
MyInvoke _myInvoke = new MyInvoke(SetText);
this.Invoke(_myInvoke, new object[] { s });
}
else
{
this.textBox6.Text = s;
}
}
3. 線程間操作無效,顯示:從不是創建控制項"Form1"的線程訪問它,是什麼原因
背景:
winform(vs2010)前台界面上有2個group(group1,group2),
每個group上面有一些lable用於顯示後台查詢出來的數據,後台3個線程A,B,C
A線程每隔幾秒查詢資料庫,並把查詢出來的數據更新到group1上的lable上(定義),
B線程每隔幾秒查詢資料庫,並把查詢出來的數據更新到group2上的lable上,通過一個輔助線程計算出的一個值賦給textBox1.text;
1.直接在窗體的構造函數中添加:
System.Windows.Forms.Control. = false;
此時禁用了所有的控制項合法性檢查。
2.通過代理來解決(msdn)
private delegate void SetTextCallback(string text); //在給textBox1.text賦值的地方調用以下方法即可 private void SetText(string text) { // InvokeRequired需要比較調用線程ID和創建線程ID // 如果它們不相同則返回true if (this.textBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.textBox1.Text = text; } }
這里主要用到了.NET中的 delegate。
另外如果線程AB只負責將數據保存在全局變數里,用一個有操作許可權的C(主界面搞個timer)調用這些數據並顯示在界面上就沒問題了。
4. C#多線程問題:線程間操作無效: 從不是創建控制項「label4」的線程訪問它。
一樓正解
你是寫在GuidProc這個類裡面的,這個是不行的.必須寫在Form的類中或者子類中.就是說:this.Invoke中的this必須指的是一個窗體對象.
補充:
原因:聲明的委託需要參數.
private delegate void SetTextDelegate(string value);
解決:修改代碼.
if (this.InvokeRequired)
{
SetLabelText d = new SetLabelText(SetLabel1);
object arg = (object)要傳入的參數值
this.Invoke(d,arg);//這里參數不對。
}
5. c#中如何跨線程調用windows控制項
在輔助線程調用(在創建輔助線程時可將此方法通過delegate傳到輔助線程中)下面的方法InvokeControl();
//寫在主線程中(windows控制項)
private void InvokeControl()
{
if (this.InvokeRequired)
this.Invoke(new DelegateChangeText(ChangeText));
else
this.ChangeText();
}
private void ChangeText()
{
this.TextBox.Text = "sd";
}
public delegate void DelegateChangeText();