我也來玩玩WinForm~BeginInvoke讓用戶體驗更好!


前言

先說明一下,本人不太做winform的項目,工作10年以來,一直奮斗在webform的舞台上,今天有機會也接觸了一下winform,下面對工作中用到的BeginInvoke方法作一下說明,和大家也一起學習一下,呵呵。

BeginInvoke產生的原因

首先一個winform程序運行后,會有一個主線程(UI),我們看到的頁面上的元素,表單,列表框等等都運行在主線程上的,主線程一阻塞,這些東西就都點不了了,呵呵,所以,在我們運行一些耗時的功能時,通常會開啟一個新的線程去干這事,這是和乎情理的,想像一下,當我們在新線程里工作時,主線程不被阻塞(不假死),用戶體驗是多么好呀,當在新線程里干完事后,把消息返回給主線程,就OK了!

美中不足

想的挺好,可惜在新線程里,干完事后,運行程序,在為主窗體元素賦值時,出錯了,說是不能訪問主線程的元素,這到是正常的,線程與線程本來就是獨立的,所以只能找其它方法了(可以使用這個方法解決上面的問題,但不推薦:  Control.CheckForIllegalCrossThreadCalls = false;)

BeginInvoke出來了

微軟為了解決上面的線程之間信息相互訪問的問題,封裝了BeginInvoke方法,它允許我們傳入一個委托,在委托方法中干這件時,這時你的主線程元素是可以被訪問的,當處理完成后,可以操縱主線程的元素,即主線程元素重新賦值。

下面是一個簡單的例子:

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            message.Text = "程序正在處理...";

            var beginInvokeThread = new Thread(() =>
            {
                var result = userBll.GeneratorUserData(dateTimePicker1.Value);//耗時工作
                #region BeginInvoke
                Func<ReturnMsg, string> funDelegate = new Func<ReturnMsg, string>(InvodeGeneratorUserData);
                IAsyncResult aResult = this.BeginInvoke(funDelegate, result);
                aResult.AsyncWaitHandle.WaitOne(-1);
                if (aResult.IsCompleted)//這里不可以訪問主線程的信息
                    MessageBox.Show(this.EndInvoke(aResult).ToString());
                #endregion
            });
            beginInvokeThread.Start();
        }

 

委托方法如下:

        /// <summary>
        /// 一個委托,把消息返回並填充到主窗體(主線程)的頁面元素上
        /// </summary>
        /// <param name="month"></param>
        /// <returns></returns>
        private string InvodeGeneratorUserData(ReturnMsg res)
        {
            this.message.Text = res.GetDescription();//這里可以訪問主線程的信息
            return res.GetDescription();
        }

 

下面是運行的效果圖:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM