在新一代的雙核電腦,要提昇程式效能,除了換新的CPU外,最好的辦法當然是軟體執行多執行續
多執行續跟一般Form表單上的Timer有什麼不同??
資源一樣都是由作業系統分配,如果多執行緒一樣寫成無限迴圈那跟Timer不也都一樣??
在這之中 如果程式小 當然都一樣,因為沒感覺,只是程式一大,在Timer裡面計時一多,問題就出來了
Timer 其實是與 表單(UI 操作介面) 共用資源的
也就是說 當在表單上 按個按鍵 畫個圖 用兩個Timer
這些動作都是同一個執行緒,只是作業系統用切割的方式,快速切換 讓這些動作感覺不出來
但某個環節寫不好,或軟體太大,Timer裡面的做的事情耗時超過Timer的區間時間 那就會發現很大的問提
Backgroundworker 是一種懶人用的多執行緒,以下簡稱 BK
用多執行緒的好處,就不多提,最少在主執行緒太忙時,會有個CPU核心會分配給另一個執行緒,在重要的事件 可以有專門處理
這樣一來可以避免Timer 常有 區間設定設不好的問題,二來增加效能
雖然是懶人用的,但用的好 還是很強大(至少在省去分配一堆有的沒有的還有Exception的一堆問題)
使用 BK 有機個步驟
1. 宣告 (-_____-!! 不宣告怎麼用...........)
這個宣告不太一樣,BK 在左邊工具箱(SDK) 是可以拉出來的,但主介面拉太多東西,在畫面編輯時會不流暢,所以我很喜歡用程式碼宣告
Dim withevents BK as backgroundworker <--這樣BK才能像SDK拉的有事件可以用
bk.WorkerReportsProgress = True <--是否可回報 這個很重要,如果要動到Form上的物件這一定要開
bk.WorkerSupportsCancellation = True <--是否可中段
2. 設定BK的動作
Private Sub bk_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bk.DoWork
.......
如果要無窮迴圈 在這寫個 Loop 就可以了
end sub
3. 執行 bk.RunWorkerAsync()
完了....................嗯 基本版的 就是這說完了
是的 很多書 大多說到這裡而已,可以媲美 Thread 的部份都沒提到,怎麼與UI互動也沒提到
再來才是重點
bk 還有兩個事件很好用,一個如果這BK不是無窮的BK
假設做完一次或做到停止,那 BK的停止事件就很好用
Private Sub bk_Complete(ByVal sander As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bk.RunWorkerCompleted
.......
end sub
寫在這裡面的事情就可以直接控制 UI ,不會有錯誤發生
但最重要的是,那在執行中呢?? 在.NET 2.0 之後,多執行緒要控制UI有很多限制,這是好的,這是避免操作的失誤,但 Therad 就必須寫很多來避免 Exception
在Bk 有個偷懶的方法
剛剛
bk.WorkerReportsProgress = True 是有意義的
加了這行,當 在 Do_work 時 可以跳出來 執行UI上的東西
用法
先寫個Class
Class CSState
Public btn As New Button
Public selectcase As Integer
Public Message As String
........(可刪減)
End Class
在 DO_work 宣告使用這 Class的物件
然後再 DO_work 使用 回報事件
Private Sub bk_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bk.DoWork
Dim myobj As CSState = CType(e.Argument, CSState) <---特殊寫法
myobj.message = "............"
myobj.selectcase = 1
bk.ReportProgress(0, myobj) <---回報事件
''''''
end sub
再來是回報事件的接收
Private Sub bk_ProgressChange(ByVal sander As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bk.ProgressChanged
Dim myObj As CSState = CType(e.UserState, CSState) <---接收剛剛傳送的事件
select case myobj.selectcase
case 1
case 2
end select
textbox1.text = myobj.message
(這邊的程式就可以直接與 UI 互動,通常用 BK寫的不會太多動作 有多那用 Select 就可以做多重選項)
end sub
這樣 就可以做到 Thread 要弄一堆控制才做得到的 多執行緒 就這樣 簡單完成了....
多執行續跟一般Form表單上的Timer有什麼不同??
資源一樣都是由作業系統分配,如果多執行緒一樣寫成無限迴圈那跟Timer不也都一樣??
在這之中 如果程式小 當然都一樣,因為沒感覺,只是程式一大,在Timer裡面計時一多,問題就出來了
Timer 其實是與 表單(UI 操作介面) 共用資源的
也就是說 當在表單上 按個按鍵 畫個圖 用兩個Timer
這些動作都是同一個執行緒,只是作業系統用切割的方式,快速切換 讓這些動作感覺不出來
但某個環節寫不好,或軟體太大,Timer裡面的做的事情耗時超過Timer的區間時間 那就會發現很大的問提
Backgroundworker 是一種懶人用的多執行緒,以下簡稱 BK
用多執行緒的好處,就不多提,最少在主執行緒太忙時,會有個CPU核心會分配給另一個執行緒,在重要的事件 可以有專門處理
這樣一來可以避免Timer 常有 區間設定設不好的問題,二來增加效能
雖然是懶人用的,但用的好 還是很強大(至少在省去分配一堆有的沒有的還有Exception的一堆問題)
使用 BK 有機個步驟
1. 宣告 (-_____-!! 不宣告怎麼用...........)
這個宣告不太一樣,BK 在左邊工具箱(SDK) 是可以拉出來的,但主介面拉太多東西,在畫面編輯時會不流暢,所以我很喜歡用程式碼宣告
Dim withevents BK as backgroundworker <--這樣BK才能像SDK拉的有事件可以用
bk.WorkerReportsProgress = True <--是否可回報 這個很重要,如果要動到Form上的物件這一定要開
bk.WorkerSupportsCancellation = True <--是否可中段
2. 設定BK的動作
Private Sub bk_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bk.DoWork
.......
如果要無窮迴圈 在這寫個 Loop 就可以了
end sub
3. 執行 bk.RunWorkerAsync()
完了....................嗯 基本版的 就是這說完了
是的 很多書 大多說到這裡而已,可以媲美 Thread 的部份都沒提到,怎麼與UI互動也沒提到
再來才是重點
bk 還有兩個事件很好用,一個如果這BK不是無窮的BK
假設做完一次或做到停止,那 BK的停止事件就很好用
Private Sub bk_Complete(ByVal sander As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bk.RunWorkerCompleted
.......
end sub
寫在這裡面的事情就可以直接控制 UI ,不會有錯誤發生
但最重要的是,那在執行中呢?? 在.NET 2.0 之後,多執行緒要控制UI有很多限制,這是好的,這是避免操作的失誤,但 Therad 就必須寫很多來避免 Exception
在Bk 有個偷懶的方法
剛剛
bk.WorkerReportsProgress = True 是有意義的
加了這行,當 在 Do_work 時 可以跳出來 執行UI上的東西
用法
先寫個Class
Class CSState
Public btn As New Button
Public selectcase As Integer
Public Message As String
........(可刪減)
End Class
在 DO_work 宣告使用這 Class的物件
然後再 DO_work 使用 回報事件
Private Sub bk_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bk.DoWork
Dim myobj As CSState = CType(e.Argument, CSState) <---特殊寫法
myobj.message = "............"
myobj.selectcase = 1
bk.ReportProgress(0, myobj) <---回報事件
''''''
end sub
再來是回報事件的接收
Private Sub bk_ProgressChange(ByVal sander As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bk.ProgressChanged
Dim myObj As CSState = CType(e.UserState, CSState) <---接收剛剛傳送的事件
select case myobj.selectcase
case 1
case 2
end select
textbox1.text = myobj.message
(這邊的程式就可以直接與 UI 互動,通常用 BK寫的不會太多動作 有多那用 Select 就可以做多重選項)
end sub
這樣 就可以做到 Thread 要弄一堆控制才做得到的 多執行緒 就這樣 簡單完成了....
文章標籤
全站熱搜

你好,請叫一下,我按照你的方法,將myobj宣告完, 結果他顯示nothing , 結果給值會出現錯錯訊息(並未將物件參考設定為物件的執行個體) Private Sub BK_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BK.DoWork ToolStripProgressBar1.Visible = True If BK.CancellationPending = False Then SeqA = 0 Do While SeqA < GPNow.Rows.Count Dim myobj As CSState = CType(e.Argument, CSState) myObj.Selectcase = "ColOneColor" myObj.Color = Color.GreenYellow BK.ReportProgress(SeqA, myObj) SeqA += 1 Loop End If End Sub
在 BK_DoWork 中 Dim myobj As CSState = CType(e.Argument, CSState) 這是接收 BK.RunWorkerAsync( Obj ) 的資料 所以依你的寫法 會得到 Nothing 只要改成 Dim myobj As new CSState 如果 myobj 要在 Do_work 執行前就建立 那要改成在 Do_Work之前 就宣告 Dim myobj As new CSState bk.RunWorkerAsync(myobj) 這樣物件才會在Do_work 中接收 Dim myobj As CSState = CType(e.Argument, CSSta) 在上面的文章 這是用在 用 BK.ReportProgress(myobj) 將物件傳到 Private Sub bk_ProgressChange(ByVal sander As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bk.ProgressChanged 這個 Function 中來接收用的