VB多線程的幾種實現方法概述


轉自https://www.cnblogs.com/birdwawe/articles/2507771.html

先說多線程:

方法 1 : CreateThread

不用多說,萬變不離其宗,這是 Win32 內創建線程的唯一系統方法,以下介紹的多線程創建方式雖然不直

接接觸這個 Win32 APi,但系統也是通過他創建的。


方法 2 : TimerSetEvent

這個函數是 Win32 系統的一個高精度計時器函數,通過調用這個函數,系統會創建一個新的線程,讓Timer

回調函數中的代碼運行在這個新線程中。


方法 3 : SHCreateThread

很多人應該沒見過這個函數,這是 shlwapi.dll 的一個導出函數,這個函數看字面也能理解是個創建多線

程的函數,而且。。。 他是基於對象操作的多線程函數,也就是說他能夠穩定的運行一些用上面2種方法創

建,但不能穩定運行的代碼。至少這個函數在 IDE 的環境下表現的中規中矩! 使用方法可查 API-GUIDE


方法 4 : 想起來了, CreateRemoteThread

創建遠程線程,經測試一點也不穩定,根本沒法說下去了,還不如直接調用 CreateThread

但,做為一種線程的創建方法,還是希望能夠熟悉一下,如果不用VB寫代碼,要寫跨進程線程,這是一個簡單易

行的辦法,否則只能繼續SetWindowHook了,熟悉匯編指令的還可以遠程分配內存寫硬編碼執行


方法 5 : 簡單說下 ActiveX 方式的多線程

論壇里面有用這種方法實現的穩定多線程,代碼雖好,但我卻不會用,在倡導綠色軟件的今天,為了一個多線

程,而注冊表里面又要多點xx,不好。。而且卸載麻煩。 用 ActiveX 創建線程與其他方式創建的線程最重

要的地方要主義,任何VB函數的調用最好都建立在新線程中新初始化的對象基礎上執行,不要跨對象調用,

而 ActiveX 的安全線程本身也正是利用了這點,不知道研究 ActiveX 的老大們有沒注意,利用他特性實

現的多線程,是初始化的一個新的線程,而這個線程中初始化的對象則是整個工程。很大的資源浪費,而且有

時候還不好控制,不是你想要的效果。總之一句話,新線程中要自己初始化新的對象而且最好不要用實例繼承


方法 6 : 我的想法

記得以前 CSDN 中有人做過一個代碼,通過函數地址抓取函數內的機器碼,如果能夠知道VB何時已將代碼進

行了機器碼的轉換,然后抓取這些代碼放到數組中執行,那應該是非常穩定的。這純屬娛樂的想法,雖然能夠

實現,但有點過分了,除非是 VB 多線程的狂熱者,否則我想不該花太多力氣研究這個。


方法 7 : 異步

論壇中很多人問,timer控件的事件中代碼是怎么運行的。其實這就是異步,對於單核CPU多線程的執行方式

與異步簡直無異。而最重要的是,VB 中用異步實現代碼執行是安全的。其實異步從大家開始Win GUI編程時

就開始接觸了。例如窗體的消息循環中就經常會以異步的方式執行,1個消息正在執行的時候,另外的消息又

被執行了,也許這樣說會覺得有些亂,稍侯解釋。這個帖子內容要說的內容就完了,下一個帖子里面有個我

忘了什么時候寫的代碼,以那個代碼為例,介紹應用異步。

==========================================================================

如何在VB6里面實現穩定的多線程

微軟官方給出的方案在MSDN里面有說,就是使用ActiveX EXE那種"單元線程模型".

我也曾經試過,的確可以實現"多線程",只是由於要多一個EXE,比較麻煩,后來就沒有深入了.

結果一次無意中在VBGOOD中看到一段代碼,才打通了一個關節:為什么不直接使用ActiveX EXE寫程序呢?!

那段代碼里面,是直接使用這種工程類型,然后在工程內使用CreateObject來生成一個新對象,這樣的話,新的對象就工作於一個單元線程內了.

其實這個我也知道,可是就沒有想到在ActiveX EXE內部使用

看來思路真的不如人.....還要多多學習,多多積累.

ActiveX EXE工程設置為"獨立啟動"后,貌似只能從Sub Main里進行初始化.

而每個對象的建立,都會調用一次這個過程,因此這個過程需要一次性運行.

但是MSDN里說得很清楚,在單元線程模型里面,全局變量的范圍只能是本單元,因此不能使用設置全局變量來完成這個過程的一次運行邏輯.

原代碼里使用了GetProp等方式,感覺不是很好,於是作了一下改進,使用事件對象來完成此工作.

Sub Main相關代碼如下:

復制內容到剪貼板 程序代碼 程序代碼
Private Const MyEvent As String = "m5home"
Dim hEvent As Long
Sub Main()
If GetEventHandle = 0 Then '由於每個新對象的建立,都要執行Main()過程,因此使用事件對象來進行判斷.
hEvent = CreateEvent(0&, False, False, MyEvent) '在單元線程下,模塊里的全局變量已經沒有用了.
frmMain.Show
End If
End Sub

Private Function GetEventHandle() As Long
GetEventHandle = OpenEvent(EVENT_ALL_ACCESS, False, MyEvent)
Call CloseHandle(GetEventHandle)
End Function

Public Function Quit()
Call CloseHandle(hEvent)
End Function

由於事件對象是系統范圍的,因此可以比較完美的完成這個工作.


同時事件對象在進程消失后,會自動釋放,也方便:)

示例代碼可以生成一個新的單元線程,並在這個線程里面顯示一個窗體,窗體進行一個大循環.

循環內沒有放入DoEvents函數,因此會造成循環所在窗體無響應.

而此時主窗體不受影響.

對象間可以通過一般的調用與事件來進行通訊.

完整的代碼,在此下載:

下載文件 點擊下載此文件

**************************改一下,添加一個簡單測試例子***********************

參考:

0. 用第三方多線程專業控件ThreadFactory.exe,

1. VBA實現多線程

 2.http://ishare.iask.sina.com.cn/f/330AA87FEk2.html


免責聲明!

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



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