1. 程式人生 > >c# Winform 多線程操作

c# Winform 多線程操作

dst oss vat event component private 過程 pre ini

主要是對一個過程需要的時間很長執行時會出現界面假死的情況

方法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();
                    }
                }
            }
        }        

c# Winform 多線程操作