r2du-soft Posted Sunday at 12:23 PM Posted Sunday at 12:23 PM I have written a piece of code where it is necessary to separate the UI Thread from my code's Thread. Due to certain reasons, I cannot share the main code, but I will provide an example here. I want the UI to remain responsive while a function is executed that includes Sleep statements and For and While loops. This creates interference with the UI, causing it to freeze. I have tried several plugins, such as one that executes a secondary function on another Thread, but I encountered errors. Another approach involved executing the secondary function in a different process, but it was cumbersome, and after the function completed, I couldn’t display its output in the UI. Overall, I want to separate the UI Thread from the code Thread so that the UI doesn’t freeze. I should mention that I also used _Timer_SetTimer and AdlibRegister, but they were not effective. Here is a small example: running it will cause the UI to freeze until the For loop completes, even though it runs successfully. expandcollapse popup;--------- Opt("MustDeclareVars", 1) #include-once #include <Constants.au3> #include <WindowsConstants.au3> #include <MsgBoxConstants.au3> #include <GUIConstants.au3> ;--------- ;--------- Global $GUI_HWNDPARENT Global $GUI_HWNDPARENT_Width = 786 Global $GUI_HWNDPARENT_Height = 502 Global $GUI_HWNDPARENT_Event_Message Global $BTN_Close Global $BTN_Maximize Global $BTN_Minimize Global $LBL_Loop_Value ;--------- _Display_Page__Downloading() Func _Display_Page__Downloading() $GUI_HWNDPARENT = GUICreate("like multi-threading", $GUI_HWNDPARENT_Width, $GUI_HWNDPARENT_Height, -1, -1, $WS_POPUPWINDOW) $BTN_Close = GUICtrlCreateButton("Close", $GUI_HWNDPARENT_Width - 77, 0, 76, 38) $BTN_Maximize = GUICtrlCreateButton("Maximize", $GUI_HWNDPARENT_Width - 77 - 76 , 0, 76, 38) $BTN_Minimize = GUICtrlCreateButton("Minimize", $GUI_HWNDPARENT_Width - 77 - 76 - 76, 0, 76, 38) $LBL_Loop_Value = GUICtrlCreateLabel('', 300, 300, 100, 20) GUISetState(@SW_SHOW) WinSetOnTop($GUI_HWNDPARENT, "", $WINDOWS_ONTOP) _Downloading() MsgBox($MB_SYSTEMMODAL, "", "Continue!") While 1 $GUI_HWNDPARENT_Event_Message = GUIGetMsg() Select Case $GUI_HWNDPARENT_Event_Message = $BTN_Maximize WinSetState($GUI_HWNDPARENT, "", @SW_MAXIMIZE) Continueloop Case $GUI_HWNDPARENT_Event_Message = $BTN_Minimize WinSetState($GUI_HWNDPARENT, "", @SW_MINIMIZE) Continueloop Case $GUI_HWNDPARENT_Event_Message = $GUI_EVENT_CLOSE OR _ $GUI_HWNDPARENT_Event_Message = $BTN_Close Exit EndSelect WEnd EndFunc Func _Downloading() For $i = 1 To 300 Step +1 GUICtrlSetData($LBL_Loop_Value, $i) Sleep(1000) Next MsgBox($MB_SYSTEMMODAL, "", "FOR,Next DONE!") EndFunc
AutoBert Posted Sunday at 01:31 PM Posted Sunday at 01:31 PM (edited) I hope i didn,t misunterstood your problem: 1 hour ago, r2du-soft said: Overall, I want to separate the UI Thread from the code Thread so that the UI doesn’t freeze. Where is a small demo source for the second threat? Why is a second thread necesarry as it seems you prefer to do one job (dl a page) and after finished doing the next job? 1 hour ago, r2du-soft said: I should mention that I also used _Timer_SetTimer and AdlibRegister, but they were not effective. Adlibregister could be very helpfull just look this small demo: expandcollapse popup#ingclude <GUIConstantsEx.au3> #include <GUIConstants.au3> #include <ListviewConstants.au3> #include <WindowsConstants.au3> #include <Array.au3> #include <GuiListView.au3> ConsoleWrite(Sqrt(1.07*1.07+1.27*1.27)&@crlf) ;TCPStartup() Global $aServers[1][3], $sTitle = "Serverstatus " Global $iPing, $iAct, $iRepeat, $iMaxRepeat = 5 ;If Not FileExists('conf.ini') Then FileWriteLine('conf.ini','autoit.de| #Region Gui $hGuiMain = GUICreate($sTitle, 248, 318, 192, 142) $idMnu_file = GUICtrlCreateMenu("File") $idMnu_file_test = GUICtrlCreateMenuItem("test", $idMnu_file) $idMnu_file_close = GUICtrlCreateMenuItem("Close", $idMnu_file) $idMnu_edit = GUICtrlCreateMenu("Edit") $idMnu_edit_conf = GUICtrlCreateMenuItem("Preferences", $idMnu_edit) $idMnu_help = GUICtrlCreateMenu("?") $idLV_Server = GUICtrlCreateListView("Name|Adresse|Port|Ping", 5, 5, 238, 288, $LVS_SORTASCENDING) _GUICtrlListView_SetColumnWidth($idLV_Server, 0, 80) _GUICtrlListView_SetColumnWidth($idLV_Server, 1, 100) _GUICtrlListView_SetColumnWidth($idLV_Server, 2, 0) ;unsichtbar _GUICtrlListView_SetColumnWidth($idLV_Server, 3, $LVSCW_AUTOSIZE_USEHEADER) GUISetState(@SW_SHOW, $hGuiMain) $hGuiConf = GUICreate("Preferences", 500, 425) $idTab_conf = GUICtrlCreateTab(10, 10, 480, 405) $idTab_conf_servers = GUICtrlCreateTabItem("Servers") GUICtrlCreateGroup("Server Hinzufügen", 30, 35, 135, 185) $idLbl_name = GUICtrlCreateLabel("Name:", 40, 60) $idInp_name = GUICtrlCreateInput("", 50, 75, 100, 20) $idLbl_adresse = GUICtrlCreateLabel("Adresse:", 40, 105) $idInp_adresse = GUICtrlCreateInput("", 50, 120, 100, 20) GUICtrlCreateLabel("Port:", 40, 145) $idInp_port = GUICtrlCreateInput("", 50, 160, 100, 20) $idBtn_addserver = GUICtrlCreateButton("Add", 70, 185, 50) $idLstServer = GUICtrlCreateList("", 180, 40, 150, 190) $idBtn_delete = GUICtrlCreateButton("Löschen", 205, 240) GUICtrlCreateTabItem("") #EndRegion Gui _getServers() _GUICtrlListView_RegisterSortCallBack($idLV_Server) While 1 $msg = GUIGetMsg(1) Switch $msg[1] Case $hGuiMain Switch $msg[0] Case $GUI_EVENT_CLOSE, $idMnu_file_close _GUICtrlListView_UnRegisterSortCallBack($idLV_Server) Exit Case $idMnu_edit_conf GUISetState(@SW_SHOW, $hGuiConf) Case $idMnu_file_test $iAct = -1 _PingIt() Case $idLV_Server _GUICtrlListView_SortItems($idLV_Server, GUICtrlGetState($idLV_Server)) $iAct = -1 $iRepeat = 0 EndSwitch Case $hGuiConf Switch $msg[0] Case $GUI_EVENT_CLOSE GUISetState(@SW_HIDE, $hGuiConf) _getServers() $iAct = -1 Case $idBtn_addserver $name = GUICtrlRead($idInp_name) $adresse = GUICtrlRead($idInp_adresse) $port = GUICtrlRead($idInp_port) $read2 = IniReadSectionNames("conf.ini") $count = UBound($read2) - 1 IniWrite("conf.ini", $name, "adresse", $adresse) IniWrite("conf.ini", $name, "port", $port) GUICtrlSetData($idInp_name, "") GUICtrlSetData($idInp_adresse, "") GUICtrlSetData($idInp_port, "") Case $idBtn_delete $read3 = GUICtrlRead($idLstServer) IniDelete("conf.ini", $read3) EndSwitch EndSwitch WEnd Func _getServers() Local $aTmp = IniReadSectionNames("conf.ini") _ArraySort($aTmp, 0, 1) Local $aData _GUICtrlListView_DeleteAllItems($idLV_Server) ReDim $aServers[$aTmp[0] + 1][2] For $i = 1 To $aTmp[0] $aData = IniReadSection("conf.ini", $aTmp[$i]) $aServers[$i][0] = GUICtrlCreateListViewItem($aTmp[$i] & '|' & $aData[1][1] & '|' & $aData[2][1], $idLV_Server) $aServers[$i][1] = $aTmp[$i] ; $aServers[$i][2]=$aData[1] ; $aServers[$i][3]=$aData[2] Next ; _ArrayDisplay($aServers) EndFunc ;==>_getServers Func _PingIt() AdlibUnRegister('_PingIt') ;first disable $iAct += 1 WinSetTitle($hGuiMain, '', $sTitle & $iRepeat+1) Local $aItem = _GUICtrlListView_GetItemTextArray($idLV_Server, $iAct) Local $iItem = _ArraySearch($aServers, $aItem[1]) ;Server aus Listview im Array suchen ConsoleWrite($iAct & @TAB & $aItem[1] & @TAB) $iPing = Ping($aItem[2]) If @error Then $iPing = 99999 ;für nicht erreichbar nötig wegen Sortiermöglichkeit ConsoleWrite($iPing & @CRLF) GUICtrlSetData($aServers[$iItem][0], '|||' & StringFormat('%5s', $iPing)) Switch $iPing ;Farben je nach Ping Case 0 To 24 GUICtrlSetBkColor($aServers[$iItem][0], 0x22C21F) GUICtrlSetColor($aServers[$iItem][0], 0x0) Case 25 To 549 GUICtrlSetBkColor($aServers[$iItem][0], 0x00FF1F) GUICtrlSetColor($aServers[$iItem][0], 0x0) Case 550 To 999 GUICtrlSetBkColor($aServers[$iItem][0], 0x772200) GUICtrlSetColor($aServers[$iItem][0], 0xFFFFFF) Case Else GUICtrlSetBkColor($aServers[$iItem][0], 0xFF0000) GUICtrlSetColor($aServers[$iItem][0], 0xFFFFFF) EndSwitch If $iAct < _GUICtrlListView_GetItemCount($idLV_Server) - 1 Then AdlibRegister('_PingIt') ;don't forget to renable Else If $iRepeat < $iMaxRepeat - 1 Then $iAct = -1 $iRepeat += 1 #cs For $iItem = 0 To _GUICtrlListView_GetItemCount($idLV_Server) GUICtrlSetColor($aServers[$iItem][0], 0x000000) GUICtrlSetBkColor($aServers[$iItem][0], 0xFFFFFF) Next #ce AdlibRegister('_PingIt') ;don't forget to reenable EndIf EndIf EndFunc ;==>_PingIt happy new year and best wishes (auto)Bert Edited Sunday at 01:34 PM by AutoBert
Nine Posted Sunday at 01:54 PM Posted Sunday at 01:54 PM You could use my Multi-Thread UDF this way : expandcollapse popup#include <Constants.au3> #include <WindowsConstants.au3> #include <MsgBoxConstants.au3> #include <GUIConstants.au3> #include "..\Files\PMT-UDF.au3" Opt("MustDeclareVars", True) Global $GUI_HWNDPARENT Global $GUI_HWNDPARENT_Width = 786 Global $GUI_HWNDPARENT_Height = 502 Global $GUI_HWNDPARENT_Event_Message Global $BTN_Close Global $BTN_Maximize Global $BTN_Minimize Global $LBL_Loop_Value _PMT_Init() _Display_Page__Downloading() Func _Display_Page__Downloading() $GUI_HWNDPARENT = GUICreate("like multi-threading", $GUI_HWNDPARENT_Width, $GUI_HWNDPARENT_Height, -1, -1, $WS_POPUPWINDOW) $BTN_Close = GUICtrlCreateButton("Close", $GUI_HWNDPARENT_Width - 77, 0, 76, 38) $BTN_Maximize = GUICtrlCreateButton("Maximize", $GUI_HWNDPARENT_Width - 77 - 76, 0, 76, 38) $BTN_Minimize = GUICtrlCreateButton("Minimize", $GUI_HWNDPARENT_Width - 77 - 76 - 76, 0, 76, 38) $LBL_Loop_Value = GUICtrlCreateLabel('Test', 300, 300, 100, 20) GUISetState(@SW_SHOW) WinSetOnTop($GUI_HWNDPARENT, "", $WINDOWS_ONTOP) Local $hProc1 = _PMT_Start("_Downloading"), $sResponse While 1 $GUI_HWNDPARENT_Event_Message = GUIGetMsg() Select Case $GUI_HWNDPARENT_Event_Message = $BTN_Maximize WinSetState($GUI_HWNDPARENT, "", @SW_MAXIMIZE) ContinueLoop Case $GUI_HWNDPARENT_Event_Message = $BTN_Minimize WinSetState($GUI_HWNDPARENT, "", @SW_MINIMIZE) ContinueLoop Case $GUI_HWNDPARENT_Event_Message = $GUI_EVENT_CLOSE Or _ $GUI_HWNDPARENT_Event_Message = $BTN_Close Exit EndSelect If $hProc1 Then $sResponse = _PMT_GetResponse($hProc1) If @error Then MsgBox($MB_OK, "Error", "Process has dropped") $hProc1 = 0 ContinueLoop EndIf If $sResponse Then If StringInStr($sResponse, "DONE") Then MsgBox($MB_OK + $MB_TOPMOST, "Success", $sResponse & @CRLF) $hProc1 = 0 Else GUICtrlSetData($LBL_Loop_Value, $sResponse) EndIf EndIf EndIf WEnd EndFunc ;==>_Display_Page__Downloading Func _Downloading() MsgBox($MB_OK + $MB_TOPMOST, "Starting", "Thread") For $i = 1 To 50 Step +1 ConsoleWrite($i) Sleep(500) Next MsgBox($MB_SYSTEMMODAL + $MB_TOPMOST, "", "FOR,Next DONE!") Return "a somewhat long message if you need to send inforation to the caller when you are DONE" EndFunc ;==>_Downloading “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now