c#之如何安全的跨线程访问控件

      在窗体开发中用到线程是很常见的事情。好比一边下载东西一边点击其余功能。若是只有一个主线程。势必只会但同一时间处理一个功能,完了以后,才会去处理下一个功能。这样的体验,相比用一次,你就不再想碰了。再好比,加入进度条控件的软件。进度条从0读取到100的过程当中,是有一个while循环的。若是你放到主线程里面执行,那就呵呵了。在这个循环中止前,你会发现你的软件绝逼处于卡死状态。鼠标都拖不动它。为了解决这类问题。咱们须要附加一个线程,至关于请一个助理,帮咱们解决循环的事。这样咱们的主线程才有闲工夫管理其余事。这样鼠标点击拖动窗体或者其余功能就不会受到影响。c#

        好了,让咱们一块儿,学习一下,怎么使用线程,以及附加的自定义线程如何安全的跨线程访问主线程中的控件。这里说明一下,全部的控件都属于主线程的,任何外来线程访问它,好比给它的属性赋值操做。都要采起安全的方式访问。这是软件开发的原则。那么如今咱们先来看看,怎么作,才是线程访问不安全的呢?安全

请看代码:学习

 
 public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;//禁止编译器对跨线程访问作检查,若是不加这一句,绝逼报错。不信你试试!
        }
        
private void button1_Click(object sender, EventArgs e)
        {
            Thread thread1 = new Thread(new ParameterizedThreadStart(UpdateLabel));
            thread1.Start("更新Label控件");
        }
        private void UpdateLabel(object str)
        {
            this.label1.Text = str.ToString();//这个线程调用了主线程中的label1控件呵呵
        }

以上就是不安全访问控件。若是你不加ui

Control.CheckForIllegalCrossThreadCalls = false;

运行是会报错的。编译器会对这种跨线程作安全检查。若是你这样直接访问,它是不容许的。因此必须禁用掉才能够的。固然咯,你禁用掉就能够正常运行了。可是这样不安全。作好不要这样使用咯。平时用的玩不要紧。工做了这样用,显得很不专业咯。下面介绍安全的跨线程访问this

不少网上这样写的。发现依然不行。虽然是建立了另一个附加进程,可是它获取了主线程的控制权,尽管不会报错,却是界面会卡死。线程

public partial class Form1 : Form
    {
        private delegate void FlushClient();//代理
        public Form1()
        {
            InitializeComponent();
        }        
        private void Form1_Load(object sender, EventArgs e)
        {
             FlushClient fc=new FlushClient(ThreadFunction); 
             fc.BeginInvoke(null,null);//使用begininvoke方法
        }
         private void ThreadFunction()
        {
              while (true)
            {
                this.textBox1.Text = DateTime.Now.ToString();
                Thread.Sleep(1000);
            }
        }
    }

下面来看看正确的跨线程姿式:代理

第一种方式:code

 delegate void done();
        private Thread thread1 = null;

        private void Form1_Load(object sender, EventArgs e)
        {
            //thread1 = new Thread(new ThreadStart(counter));
            thread1 = new Thread(new ThreadStart(crossthread));
            thread1.IsBackground = true;
            thread1.Start();
        }

        private void crossthread() {
            while (true)
            {
                Thread.Sleep(1000);
                dowork();
            }

        }

        private void dowork() {
            if (this.txt_count.InvokeRequired) {
                done Done = new done(dowork);
                this.Invoke(Done);
            }
            else
            {
                    this.txt_count.Text = DateTime.Now.ToString();
            }
   
        }

近两天会更新更多的方式。。。暂时写到这么多。楼主要睡觉了嘻嘻orm

相关文章
相关标签/搜索