以下引用自: c#使用MethodInvoker解决跨线程访问控件
net 原则上禁止跨线程访问控件,因为这样可能造成错误的发生,有一种方法是禁止编译器对跨线程访问作检查,Control.CheckForIllegalCrossThreadCalls = false;可以实现访问,但是出不出错不敢保证C#跨线程访问控件运行时错误。
使用MethodInvoker即可解决
看看系统定义, 与event 的区别
public delegate void MethodInvoker();
public delegate void EventHandler(object sender, EventArgs e);
简单来说 :
MethodInvoker 是不带参数的委托。
EventHandler 是可带参数的委托
我是这样理解的, 开启新线程 threadRun, 在新线程中使用MethodInvoker 委托执行 run()方法, 这个时候 run() 方法其实是在主线程中执行的, 这样就避免了 跨线程访问控件, 以下是我的测试代码:
private void button1_Click(object sender, EventArgs e)
{
Thread.CurrentThread.Name = "MainThread"; //主线程命名为 MainThread
Thread td = new Thread(threadRun);
td.Name = "ChildThread"; //子线程命名为 ChildThread
td.Start();
}
private void ChangeText()
{
this.textBox1.Text = Thread.CurrentThread.Name; //TextBox1内容被修改的线程的名字
}
private void threadRun()
{
MessageBox.Show(Thread.CurrentThread.Name); //弹出对话框, 当前运行线程的名字
MethodInvoker In = new MethodInvoker(ChangeText);
this.BeginInvoke(In);
运行后, 点击 Button 首先弹出对话框 ChildThread, 然后 TextBox1 改为 MainThread
然后我的牛角劲又来了, ChangeText 被 MethodInvoker 插入到主线程中运行, 那么 ChangeText 应该是在 button1_Click 完全结束后才运行吧, 测试代码
private void button1_Click(object sender, EventArgs e)
{
Thread.CurrentThread.Name = "MainThread"; //主线程命名为 MainThread
Thread td = new Thread(threadRun);
td.Name = "ChildThread"; //子线程命名为 ChildThread
td.Start();
int k=0; //让主线程全速运行一段时间
for (long i = 0; i < 1000000000; i++)
{
if (k > 10000) k = 0;
k = k+5;
}
MessageBox.Show("MainThread全速运算刚刚结束了");
}
private void ChangeText()
{
MessageBox.Show(Thread.CurrentThread.Name); //弹出执行ChangeText的线程的名字
}
private void threadRun()
{
MessageBox.Show(Thread.CurrentThread.Name); //弹出对话框, 当前运行线程的名字
MethodInvoker In = new MethodInvoker(ChangeText);
this.BeginInvoke(In);
}
可惜并不是我想的那样, 运行情况是先弹出 ChildThread, 然后弹出 MainThread, 最后才弹出 MainThread全速运算刚刚结束了
有谁可以解释一下么???????????? 难道同一个线程也有CPU时间片的概念? 以前听说过线程插入进程, 但没听说过 线程也可以被插入啊?
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/12324.html