c# Winform 多线程操作

主要是对一个过程需要的时间很长执行时会出现界面假死的情况

方法1:

Application.DoEvents(),这种方法当你拖动窗体时,界面不会假死。但在你拖动时代码不再执行,也就是阻塞了,当你不再控制窗体时会继续执行,其实这还是一个单线程

  for (int i = 0; i < 10000; i++)
            {
                for (int j = 0; j < 100000; j++)
                {

                    textBox1.Text = i.ToString() + " " + j.ToString();
                    Application.DoEvents();
                }
            }

方法2:多线程

       2.1:取消控件跨线程检测

               2.1.1取消窗体内控件的跨线程检查(单个控件取消也可以)    

        public Form1()
        {
            InitializeComponent();
            CheckForIllegalCrossThreadCalls = false;//干掉检测 不再检测跨线程
        }

               2.1.2新建线程实现跨线程访问

        /// <summary>
        /// 新建线程并执行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            ThreadStart thStart = new ThreadStart(Pro);//threadStart委托 
            Thread thread = new Thread(thStart);
            thread.Priority = ThreadPriority.Highest;
            thread.IsBackground = true; //关闭窗体继续执行
            thread.Start();

        }



        public void Pro()
        {

            for (int i = 0; i < 10000; i++)
            {
                for (int j = 0; j < 100000; j++)
                {                   
                        textBox1.Text = j.ToString();
                }
            }
        }

       2.2:主线程中操作

    2.2.1 不用取消跨线程访问

        /// <summary>
        /// 新建线程并执行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            ThreadStart thStart = new ThreadStart(Pro);//threadStart委托 
            Thread thread = new Thread(thStart);
            thread.Priority = ThreadPriority.Highest;
            thread.IsBackground = true; //关闭窗体继续执行
            thread.Start();
        }

        public void Pro()
        {
            for (int i = 0; i < 10000; i++)
            {
                for (int j = 0; j < 100000; j++)
                {
                    if (textBox1.InvokeRequired)//不同线程访问了
                        textBox1.Invoke(new Action<TextBox, string>(SetTxtValue), textBox1, j.ToString());//跨线程了
                    else//同线程直接赋值
                        textBox1.Text = j.ToString();
                }
            }
        }

        private void SetTxtValue(TextBox txt, string value)
        {
            txt.Text = value;
        }

 注:多个线程同时访问一个方法时 需要锁定

        public static readonly object obj = new object();
        public void Pro()
        {
            //lock(obj){}=Monitor.Enter(obj)  Monitor.Exit(obj)
            lock (obj)
            {
                for (int i = 0; i < 10000; i++)
                {
                    for (int j = 0; j < 100000; j++)
                    {
                        if (textBox1.InvokeRequired)//不同线程访问了
                            textBox1.Invoke(new Action<TextBox, string>(SetTxtValue), textBox1, j.ToString());//跨线程了
                        else//同线程直接赋值
                            textBox1.Text = j.ToString();
                    }
                }
            }
        }        

猜你喜欢

转载自www.cnblogs.com/SoftWareIe/p/9650947.html