分享

[C#][WinForm]UI別在無回應了

 simplelam 2014-11-14

 網友問題,這裡大概簡單實作並記錄。

一般初期大家都以單執行緒為主,但後期需求變多或要處理大量耗時作業

單一執行緒幾乎無法滿足我們的需求,而且還會被使用者抱怨程式用起來很卡或無回應(看個人造化!遇到好user算祖上積德XD)。

遇到這樣的狀況,大多使用者都會強制關閉程式(UI執行緒在沒把主控權交還給Windows前是凍結的)

使用單一執行緒幾乎都躲不了這樣的宿命,所以就得靠多執行緒來改善這樣的問題。

  

行為:執行大量新增作業(100000筆資料) 

初始畫面

image

01DataTable dt;
02 bool flag;
03private void Form1_Load(object sender, EventArgs e)
04        {
05            InitData();
06            ThreadPool.SetMinThreads(2, 5);
07            ThreadPool.SetMaxThreads(4, 10);
08        }  
09 
10 
11private void InitData()
12        {
13            dt = new DataTable("table1");
14            dt.Columns.Add("c1");
15            dt.Columns.Add("c2");
16            Random rnd = new Random();
17            for (Int32 i = 1; i <= 10; i++)
18            {
19                DataRow row = dt.NewRow();
20                row["c1"] = rnd.Next(1, 100);
21                row["c2"] = "i_am_c2";
22                dt.Rows.Add(row);
23            }
24            dataGridView1.DataSource = dt; 
25        }

單一執行緒(新增資料)

01private void button1_Click(object sender, EventArgs e)
02        {          
03            flag = true;         
04            //單一執行緒
05            AddRow();
06            //將job丟入ThreadPool Queue
07            //主緒繼續處理畫面
08            //ThreadPool.QueueUserWorkItem(new WaitCallback(AddRow));
09        
10 
11 private void AddRow()
12        {
13            if (flag)
14            {
15                for (Int32 i = 1; i <= 100000; i++)
16                {
17                    DataRow dr = dt.NewRow();
18                    dr["c1"] = i.ToString();
19                    dr["c2"] = "hello";
20                    dt.Rows.Add(dr);
21                    label1.Text = "總共筆數:" + dt.Rows.Count.ToString();
22                    if (i % 500 == 0)
23                    {                      
24                        dataGridView1.FirstDisplayedScrollingRowIndex = dt.Rows.Count;
25                    }
26                }
27            }
28            else                         
29                return;                        
30        }          

執行畫面果然完全凍結,而且畫面也無法重畫(一片白),這時任誰都會想按下ctrl+alt+del。

image 

使用ThreadPool來改善

01private void button1_Click(object sender, EventArgs e)
02        {          
03            flag = true;         
04            //單一執行緒
05            //AddRow();
06            //將job丟入ThreadPool Queue
07            //主緒繼續處理畫面
08            ThreadPool.QueueUserWorkItem(new WaitCallback(AddRow));
09        
10 
11//宣告delegate
12delegate void MyInvoke(String status);
13        private void UpdateLab(String status)
14        {
15            label1.Text = status;
16        }      
17 
18        delegate void MyInvoke2(Int32 index);
19        private void DisplayDataGridView(Int32 index)
20        {          
21            dataGridView1.FirstDisplayedScrollingRowIndex = index;
22        }
23 
24private void AddRow(object arg)
25        {          
26            if (flag)
27            {
28                for (Int32 i = 1; i <= 100000; i++)
29                {                  
30                    DataRow dr = dt.NewRow();
31                    dr["c1"] = i.ToString();
32                    dr["c2"] = "hello";
33                    dt.Rows.Add(dr);
34                    MyInvoke mi = new MyInvoke(UpdateLab);
35                    //使用主緒更新Label
36                    Invoke(mi, "總共筆數:" + dt.Rows.Count.ToString());                   
37                    Thread.Sleep(1); 
38                    if (i % 500 == 0)
39                    {
40                        MyInvoke2 mi2 = new MyInvoke2(DisplayDataGridView);
41                        //使用主緒更新DataGridView
42                        Invoke(mi2,i);
43                    }                   
44                }
45            }
46            else                         
47                return;           
48        }

使用ThreadPool後,UI終於可隨意拖拉,UI裡的物件也可即時重畫,在也不會發生無回應或很卡的狀況了。

image image


DotBlogs Tags: C# WinForm

關連文章

[C#][Tips]迴圈中別建立執行個體

[C#][WinForm]擺脫密碼透視小工具

[C#][Tips]比較Int32.TryParse、Int32.Parse And Convert.ToInt32

[C#][WinForm]如何合併圖片

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多