天天看點

BackgroundWorker 簡單使用教程 多個線程的建立

BackgroundWorker是一個非常不錯的線程控件,能避免界面假死,讓線程操作你想要做的事,它學習起來很簡單,但是能實作很強大的功能。釋出這篇文章的目的是将最近學習到的共享出來,大家交流一下,當然我也是菜鳥,在這裡你将學習到BackgroundWorker簡單使用,停止,暫停,繼續等操作,BackgroundWorker比起<code>Thread和</code><code>ThreadPool要簡單太多,為了更友善在實際應用中使用,我使用的是winform,沒有使用控制台程式。</code>

<code>在UI界面裡拖動一個button和richTextBox到界面。</code>

我會從最簡單的開始,隻有最簡單的代碼才會讓人有繼續學下去的欲望,下列代碼可以将1到999列印到richTextBox1控件上。

但是很不幸,以上代碼會報錯,報錯資訊:線程間操作無效: 從不是建立控件“richTextBox1”的線程通路它。

那麼我們繼續改造代碼,讓數字顯示在richTextBox1控件上,并且讓richTextBox1焦點處于最低端。

上面是BackgroundWorker一個最簡單的例子,沒有多餘複雜的代碼,這就是BackgroundWorker,下面我們加入停止按鈕,讓線程停下來。

再拖動一個button控件到界面,讓線程停止我們先要改造一下代碼,讓button事件也能控制到BackgroundWorker線程。

為了避免代碼的複雜化,上面代碼我沒有做更多的體驗修改,比如點選開始的按鈕,開始的按鈕應該為不可用狀态,點選停止按鈕後停止按鈕不可用狀态,激活開始按鈕。

下面我們将繼續更新,如何來獲知線程是否已經執行完成或者線程已經停止了呢

到現在為止你可以自己去用BackgroundWorker建立一個線程了,你已經了解它了,當然BackgroundWorker還有一個ReportProgress滾動條事件,可以顯示進度,我暫且認為它是多餘的,因為大部分進度都可以通過bw_DoWork來控制實作。下面我們繼續完善BackgroundWorker,加入暫停和繼續功能。

再拖動一個button控件到界面,BackgroundWorker的暫停和繼續我們使用ManualResetEvent。

到目前為止BackgroundWorker的大部分功能都實作了,上面的代碼在很多部落格中都能找到,都是隻執行了一個背景線程。如果我們有1千個耗時的任務,那麼一個線程遠遠不夠,我們需要建立多條線程,讓他分段執行,比如建立10個線程,把1千個任務分成不同的等分讓10個線程分别去執行。

我們使用list泛型 List&lt;BackgroundWorker&gt;,然後使用bw.RunWorkerAsync(i) 傳遞參數到bw_DoWork裡,在bw_DoWork裡使用e.Argument接受參數。

由于上面代碼不是耗時操作,又開啟線程10個,操作過快,造成界面假死狀态,可以使用Sleep讓線程休眠。

我們繼續完善代碼,加入停止操作,加入完成後和停止的事件,由于是多線程,判斷是線程操作是否完成,我們用bws.Remove(sender as BackgroundWorker); 方法删除線程,然後使用bws.Count == 0來判斷是否操作完成。

上面代碼中的停止不是能立即停止,這個就和開車一樣,開的越快,刹車的後拖行的距離越長,同理,開啟的線程的越多,完全暫停需要的時間越長,不知我說的是否正确。另外我也想問一下是否能真正的全部線程停止,點停止後全部線程立即停止。

下面我們繼續加入暫停和繼續的功能,一樣的道理,我們使用List&lt;ManualResetEvent&gt;。

至此,所有的代碼都奉上了,多個線程操作會帶來很多意向不到的麻煩,比如多個線程同時把資料寫入一個檔案,多線程更新datatable等,會讓軟體莫名其妙的自動退出,.net2.0裡還沒有絕對線程安全的資料集,很多大佬都說用lock,但我對lock也是一知半解,還請大家賜教賜教,如上有什麼說的不對,也請大家多多指點。

繼續閱讀