天天看點

Autoit裡用多程序模拟多線程

一直以來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("函數名稱")。 例子:
  1. #NoTrayIcon
  2. #include "CoProc.au3"
  3. #region 主程式區域
  4. #include <GUIConstants.au3>
  5. $Form1 = GUICreate("Multiple File Download", 622, 119, 192, 125)
  6. GUICtrlCreateLabel("http://www.mv.com/test/paths.txt (1Mb)", 8, 8)
  7. GUICtrlCreateLabel("http://support.shaw.ca/troubleshooting/files/download.dat (20Mb)", 8, 48)
  8. $Progress1 = GUICtrlCreateProgress(8, 24, 601, 17)
  9. $Progress2 = GUICtrlCreateProgress(8, 64, 601, 17)
  10. $Button1 = GUICtrlCreateButton("Pause", 8, 88, 81, 25)
  11. $Button2 = GUICtrlCreateButton("Resume", 96, 88, 81, 25)
  12. $iPidSmall = _CoProc("Small") ;開啟子程序,子程序将執行Small()函數,$iPidSmall得到的是子程序的PID
  13. $iPidBig = _CoProc("Big")
  14. GUISetState(@SW_SHOW)
  15. _CoProcReciver("Reciver") ;注冊Reciver()函數來接收子程序傳遞過來的消息
  16. While 1
  17.     $msg = GuiGetMsg()
  18.     Select
  19.     Case $msg = $GUI_EVENT_CLOSE
  20.         ExitLoop
  21.     Case $msg = $Button1
  22.           _ProcSuspend($iPidSmall) ;暫停$iPidSmall這個子程序
  23.           _ProcSuspend($iPidBig)
  24.     Case $msg = $Button2
  25.           _ProcResume($iPidSmall) ;恢複$iPidSmall子程序
  26.           _ProcResume($iPidBig)
  27.     Case Else
  28.         ;
  29.     EndSelect
  30. WEnd
  31. FileDelete(@TempDir & "smalltest.tmp")
  32. FileDelete(@TempDir & "bigtest.tmp")
  33. Exit
  34. Func Reciver($vParameter)
  35.     ;$vParameter裡就是子程序發來的消息
  36.     $aParam = StringSplit($vParameter,"|")
  37.     If $aParam[1] = "small" Then GUICtrlSetData($Progress1,$aParam[2])
  38.     If $aParam[1] = "big" Then GUICtrlSetData($Progress2,$aParam[2])
  39. EndFunc
  40. #endregion
  41. #region Small()函數裡是'Small file'子程序的所要執行的代碼
  42. Func Small()
  43.     $url = "http://www.mv.com/test/paths.txt"
  44.     $size = InetGetSize($url)
  45.     InetGet($url,@TempDir & "smalltest.tmp",1,1)
  46.     While @InetGetActive And ProcessExists($gi_CoProcParent)
  47.         ;在下載下傳時不斷向父程序發送下載下傳進度,$gi_CoProcParent是父程序的PID,這個變量是函數自己建立的
  48.           _CoProcSend($gi_CoProcParent,"small|" & Round(@InetGetBytesRead / $size * 100,0))
  49.         Sleep(250)
  50.     WEnd
  51.       _CoProcSend($gi_CoProcParent,"small|100")
  52. #region 'Big file'子程序執行的代碼
  53. Func Big()
  54.     $url = "http://support.shaw.ca/troubleshooting/files/download.dat"
  55.     InetGet($url,@TempDir & "bigtest.tmp",1,1)
  56.           _CoProcSend($gi_CoProcParent,"big|" & Round(@InetGetBytesRead / $size * 100,0))
  57.       _CoProcSend($gi_CoProcParent,"big|100")

複制代碼

注意事項: 子程序發送消息時需要母程序的PID,而母程序的PID儲存在$gi_CoProcParentli裡 子程序可以正常使用腳本裡的所有自定義函數 在子程序執行的那個函數裡你不能再#include函數庫或是用Func定義函數 對一個子程序不要重複使用_ProcSuspend()和_ProcResume() 函數,否則會讓子程序無響應