一直以來Autoit都不支援多線程,是以一些需要同時運作多個循環的操作也就無法實作。這個問題在其它的某些語言裡也經常出現,解決的方法就是使用多程序。 所謂多程序,就是同時運作多個子程序,每個子程序負責不同的操作,藉此達到和多線程相當的效果。Autoit本身已經具備了實作多程序的條件,且已經有人完成了相關的自定義函數。下面我将具體講解如何利用這些自定義函數實作多程序。 首先到 http://www.autoitscript.com/foru ... 29326&hl=CoProc 下載下傳 CoProc.zip ,壓縮包裡的CoProc.au3包含了實作多程序的相關函數,你可以把這個檔案複制到Include目錄下。 函數使用說明: _CoProc() 這個函數的作用是啟動自己的子程序,然後執行指定的函數。比方說如果你想另開一個程序執行“fuck”函數,代碼寫_CoProc("fuck")就行了。這個函數會傳回子程序的PID,在對子程序進行操作時會用到這個PID。另外,你可以無限制開啟子程序,且每個子程序都可以建立完全獨立的GUI。 _ProcSuspend() & _ProcResume() 暫停/恢複程序。如果你開了一個子程序專門下載下傳檔案,就可以利用這兩個函數暫停/繼續下載下傳。範例:_ProcSuspend(@PID) 。 _CloseHandle() 關閉子程序。範例:_CloseHandle(@PID) 。 _CoProcSend() 向指定程序發送消息。當子程序有新的資訊(比如完成下載下傳)需要提示母程序時,就可以使用這個函數。範例:_CoProcSend($PID, "發送的消息内容")。 _CoProcReciver() 注冊一個函數用于接收其他程序用_CoProcSend函數傳遞過來的消息,每當收到消息時注冊的函數就會被執行。需要注意的是,被注冊的函數必須有且隻有一個自定義參數,而傳遞的參數裡就是發送過來的消息。範例:_CoProcReciver("函數名稱")。 例子: - #NoTrayIcon
- #include "CoProc.au3"
- #region 主程式區域
- #include <GUIConstants.au3>
- $Form1 = GUICreate("Multiple File Download", 622, 119, 192, 125)
- GUICtrlCreateLabel("http://www.mv.com/test/paths.txt (1Mb)", 8, 8)
- GUICtrlCreateLabel("http://support.shaw.ca/troubleshooting/files/download.dat (20Mb)", 8, 48)
- $Progress1 = GUICtrlCreateProgress(8, 24, 601, 17)
- $Progress2 = GUICtrlCreateProgress(8, 64, 601, 17)
- $Button1 = GUICtrlCreateButton("Pause", 8, 88, 81, 25)
- $Button2 = GUICtrlCreateButton("Resume", 96, 88, 81, 25)
- $iPidSmall = _CoProc("Small") ;開啟子程序,子程序将執行Small()函數,$iPidSmall得到的是子程序的PID
- $iPidBig = _CoProc("Big")
- GUISetState(@SW_SHOW)
- _CoProcReciver("Reciver") ;注冊Reciver()函數來接收子程序傳遞過來的消息
- While 1
- $msg = GuiGetMsg()
- Select
- Case $msg = $GUI_EVENT_CLOSE
- ExitLoop
- Case $msg = $Button1
- _ProcSuspend($iPidSmall) ;暫停$iPidSmall這個子程序
- _ProcSuspend($iPidBig)
- Case $msg = $Button2
- _ProcResume($iPidSmall) ;恢複$iPidSmall子程序
- _ProcResume($iPidBig)
- Case Else
- ;
- EndSelect
- WEnd
- FileDelete(@TempDir & "smalltest.tmp")
- FileDelete(@TempDir & "bigtest.tmp")
- Exit
- Func Reciver($vParameter)
- ;$vParameter裡就是子程序發來的消息
- $aParam = StringSplit($vParameter,"|")
- If $aParam[1] = "small" Then GUICtrlSetData($Progress1,$aParam[2])
- If $aParam[1] = "big" Then GUICtrlSetData($Progress2,$aParam[2])
- EndFunc
- #endregion
- #region Small()函數裡是'Small file'子程序的所要執行的代碼
- Func Small()
- $url = "http://www.mv.com/test/paths.txt"
- $size = InetGetSize($url)
- InetGet($url,@TempDir & "smalltest.tmp",1,1)
- While @InetGetActive And ProcessExists($gi_CoProcParent)
- ;在下載下傳時不斷向父程序發送下載下傳進度,$gi_CoProcParent是父程序的PID,這個變量是函數自己建立的
- _CoProcSend($gi_CoProcParent,"small|" & Round(@InetGetBytesRead / $size * 100,0))
- Sleep(250)
- WEnd
- _CoProcSend($gi_CoProcParent,"small|100")
-
-
- #region 'Big file'子程序執行的代碼
- Func Big()
- $url = "http://support.shaw.ca/troubleshooting/files/download.dat"
-
- InetGet($url,@TempDir & "bigtest.tmp",1,1)
-
- _CoProcSend($gi_CoProcParent,"big|" & Round(@InetGetBytesRead / $size * 100,0))
-
-
- _CoProcSend($gi_CoProcParent,"big|100")
-
-
複制代碼 注意事項: 子程序發送消息時需要母程序的PID,而母程序的PID儲存在$gi_CoProcParentli裡 子程序可以正常使用腳本裡的所有自定義函數 在子程序執行的那個函數裡你不能再#include函數庫或是用Func定義函數 對一個子程序不要重複使用_ProcSuspend()和_ProcResume() 函數,否則會讓子程序無響應 |