我用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"});
看了这个举例,问题解决了。而且事例也时非常的简单实用。