码迷,mamicode.com
首页 > 编程语言 > 详细

c#中 线程访问控件的解决方法 可直接调用此方法

时间:2017-11-08 13:13:44      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:windows   理解   class   event   component   信息   public   click   查找   

问题

由于在初学c#的时候 使用了 线程委托去执行函数,是为了不让软件窗体假死。所以使用下方代码:

Thread th = new Thread(Getform); //创建线程
th.Start();

在使用前需要引入 : using System.Threading;

 

但是,在Getform 函数中,我调用了修改窗体控件内容的命令。

textbox.text="假";

直接报错了。

线程间操作无效: 从不是创建控件“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

c#中 线程访问控件的解决方法 可直接调用此方法

标签:windows   理解   class   event   component   信息   public   click   查找   

原文地址:http://www.cnblogs.com/lazysoft/p/7803399.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!