天天看点

C# 子线程访问主窗体控件(转载)

我用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"});

看了这个举例,问题解决了。而且事例也时非常的简单实用。