Jump to content

Recommended Posts

Posted

 

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.

 

;---------
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

 

Posted (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:

#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 by AutoBert
Posted

You could use my Multi-Thread UDF this way :

#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

 

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...