由于在初学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