我用C# 編寫了一個主窗體,裡面通過按鈕控制打開一個新線程:
private void serverstart_Click(object sender, EventArgs e)
{
thThreadRead = new Thread(new ThreadStart(Listen));
thThreadRead.Start();//啟動線程
}
線程裡面我想對主窗體中的Listbox進行操作(add添加資料),直接操作控件的話會出錯,請問該怎麼操作?
是的,
在其他線程裡,不允許調用主線程建立的控件~!!!!
這樣做,是不安全的,是以,2.0屏蔽了這個~
樓上說的很對,用委托,具體代碼如下~:
public delegate void MyInvoke(string str);
private void button9_Click(object sender, EventArgs e)
{
//_myInvoke = new MyInvoke(SetText);
//CheckForIllegalCrossThreadCalls = 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;
}
}
這個确實能夠解決問題,不過不用委托也可以解決。
.net 原則上禁止跨線程通路控件,因為這樣可能造成錯誤的發生,推薦的解決方法是采用代理,用代理方法來間接操作不是同一線程建立的控件。
第二種方法是禁止編譯器對跨線程通路作檢查,可以實作通路,但是出不出錯不敢保證Control.CheckForIllegalCrossThreadCalls = false;
http://381616212.blog.163.com/blog/static/237059012007514105636929/
這兩天一直都在做公司的GPS伺服器軟體,在今天的工作遇到了一個小問題:線上程中通路Form的控件的時候總提示(線程間操作無效:從不是建立線程的控件***線程通路它)。在網上查了半天終于弄明白怎麼回事了。原來線上程中是不允許通路控件的。主要是為了線程的安全考慮。是以線上程中要通路Form中的控件就必須使用委托。下面是一位仁兄釋出在論壇上的答案:
你出現這個問題主要是因為你線上程方法中操作了界面上的控件..lstPrime.Items.Add()
可以這樣改下..
//定義一個委托
public delegate void MyInvoke(string str);
//定義一個操作界面的方法
private void UpdateUI(string str)
{
//增加項
this.lstPrime.Items.Add(str);
}
//線上程的方法中,即你的Generate方法..
//裡面隻要是涉及到Items.Add操作的都改成如下形式即可..
//比如lstPrime.Items.Add(2);改成:
MyInvoke mi=new MyInvoke(UpdateUI);
this.BeginInvoke(mi,new object[]{"2"});
看了這個舉例,問題解決了。而且事例也時非常的簡單實用。