c#關於異步線程調用UI的心得

異步線程調用UI更新,有兩種方式,一、用UI對象的Invoke方法用委託的方式進行調用操作UI的代碼,二、用事件驅動模式的BackGroundWorker組件進行UI操作,這是爲了線程安全。因爲BackGroundWorker是一個較爲常規的組件,在此不再多述,只就第一種方式進行簡單講解。

當然在編程過程中,線程安全要求,並非強制性的,因爲即便線程不安全,程序也有很大的機率能夠正常運行,不過不建議這麼做,這會給程序帶來很大的隱患。而且如果你想在這種線程不安全的情況下使用VS開發工具進行調試的話,一般情況下不會通過,因爲VS會主動引發InvalidOperationException異常來對你進行提醒,並且中斷你的調試,除非你在程序運行上下文中進行了如下設置:將Control.CheckForIllegalCrossThreadCalls設置爲false,用以禁用異常的產生,纔可以進行調試。

切記,如果要使用UI對象的Invoke方法從異步線程更改UI,若非萬不得已,此操作則最好僅用來操作UI更新,不要夾雜無關的邏輯處理代碼,不然依舊會耗費界面線程的佔用時間,造成反應遲緩或者假死。

如,這樣寫是不對的:

        private void button1_Click(object sender, EventArgs e)
        {
            //開啓一個異步線程進行邏輯處理
            new Task(new Action(() =>
            {
                //無關UI的耗時操作
                Thread.Sleep(5000);
                //調用UI線程進行界面更新
                this.Invoke(new Action(() =>
                {
                    //更新界面
                    this.Text = "233";
                    //其他無關UI的耗時操作,寫在這裏是不對的
                    Thread.Sleep(3000);
                }));
            })).Start();
        }

應該這樣寫:

        private void button1_Click(object sender, EventArgs e)
        {
            //開啓一個異步線程進行邏輯處理
            new Task(new Action(() =>
            {
                //無關UI的耗時操作
                Thread.Sleep(5000);
                //調用UI線程進行界面更新
                this.Invoke(new Action(() =>
                {
                    //更新界面
                    this.Text = "233";
                }));
                //其他無關UI的耗時操作
                Thread.Sleep(3000);
            })).Start();
        }

讓UI線程僅處理與顯示相關的代碼,可大幅度提升程序的響應速度和程序用戶的使用體驗,至於數據邏輯,除非必要,交給其他線程即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章