由于在初学c#的时候 使用了 线程委托去执行函数,是为了不让软件窗体假死。所以使用下方代码:
Thread th = new Thread(Getform); //创建线程
th.Start();
在使用前需要引入 : using System.Threading;
但是,在Getform 函数中,我调用了修改窗体控件内容的命令。
textbox.text="假";
直接报错了。
class="title text_overflow">线程间操作无效: 从不是创建控件“textbox”的线程访问它
好吧。查找资料,进行查看解决方法、
1、直接忽略线程权限的检查。
public Form1()
{
InitializeComponent();
Control.CheckForIllegalCrossThreadCalls = false;
}
我们加入了这段代码:Control.CheckForIllegalCrossThreadCalls = false; //忽略线程权限检查
个人理解:这样直接忽略也可能有其他的问题,所以大家都是不推荐的,但是也确实在某些时候可以使用,毕竟 方便。。。
2、使用委托进行安全的修改,使用delegate和invoke来从其他线程中控制控件信息(网络复制说明)
网络上的代码 直接复制在C#中查看更加明显
public partial class Form1 : Form { private delegate void FlushClient();//代理 public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { Thread thread = new Thread(CrossThreadFlush); thread.IsBackground=true; thread.Start(); } private void CrossThreadFlush() { //将代理绑定到方法 FlushClient fc = new FlushClient(ThreadFuntion); this.BeginInvoke(fc);//调用代理 } private void ThreadFuntion() { while (true) { this.textBox1.Text = DateTime.Now.ToString(); Thread.Sleep(1000); } } }
看起来还是相对很简单的,只是这种会让窗口无响应,因为在无限的刷新窗口,但是。会不会有更好的处理方法呢。
最终的解决方法:
private void button1_Click(object sender, EventArgs e) { var th = new Thread(() => { //label1.Enabled = false; label1.CrossThreadCalls(() => { label1.Enabled = !label1.Enabled; }); WriteMessage(DateTime.Now.ToString()); }); th.IsBackground = true; th.Start(); } public void WriteMessage(string msg) { label1.CrossThreadCalls(() => { label1.Text = msg; }); }
在使用前,我们新建一个类。
using System.Threading; using System.Windows.Forms; namespace WindowsFormsApplication1 { public static class Class1 { /// <summary> /// 跨线程访问控件 在控件上执行委托 /// </summary> /// <param name="ctl">控件</param> /// <param name="del">执行的委托</param> public static void CrossThreadCalls(this Control ctl, ThreadStart del) { if (del == null) return; if (ctl.InvokeRequired) ctl.Invoke(del, null); else del(); } } }
最终,我们得出了这种解决方法。还算是不错。
我只是在学习过程中记录,欢迎大家探讨
原文地址:http://www.lazyw.org/weituo.html