Jump to content

Help with delay in ListView (may need multi-process)


Go to solution Solved by Nine,

Recommended Posts

Posted

I already have a ListView that is working great and performant. Performant until adding the part which adds delay problem.

I use WM_NOTIFY with Case $LVN_ITEMCHANGED to populate other areas of my GUI successfully with keyboard navigation and mouse clicks.

Problem: There is one small part of my GUI that needs to be populated in this same method, but unfortunately it must rely on the STDOUT of another command line utility. So naturally, as expected, this causes a noticeable delay when navigating through each ListView item.

I don't know if I need another script (compiled to exe) to run as a second process to run the command line utility with STDOUT and return the output back to the main process so that I don't cause the delay in the ListView. I understand that the control that I'm trying to populate will have a slight delay before populating and I am OK with that. I just don't want to hold up the ListView.

I just don't know what is the most simplistic, most efficient way to go about this. It would be just one variable that would be used to populate the control and would essentially be True or False. I am not 100% sure if I absolutely need multi-process or not. I have thought about maybe storing the result (True or False) in a registry key or INI file and retrieving it.

Thank you for your time. I am at a dead end right now on this one.

Posted
Posted

@argumentum Thank you for your response. I'm going to do some research into the IPC stuff later today.

@Nine I was able to remove a lot of stuff out of my script so that I can post it here.

$iMsstylesFileName is the label being populated with the theme Msstyle filename. This is populated with the GetMsstyles() func. This is populated instantly because there is no waiting for STDOUT on this one.

$iAnswer is the label being populated with a True or False. But for the purpose of this example and not including an external binary, I am just getting the STDOUT from the "whoami" command line. This is populated with the IsMsstylesPatched()  func. This is the one causing the delay with ListView because it is waiting on STDOUT from the "whoami" command line.

If we comment out IsMsstylesPatched() then we can see how fast the ListView normally functions.

  Reveal hidden contents

 

  • Solution
Posted (edited)

I see.  Unless "whoami" process can be loaded once and run all the time, instead of calling it (with run) every time, there is not much value to try multi-threading or IPC.  Maybe there is a dll that could return your request, that way you would get the answer instantly.

Nevertheless, if you want to speed up your code, you should replace ProcessWaitClose with your own.  As per help file :

  Quote

The process is polled approximately every 250 milliseconds.

Expand  

Which is quite slow.  You could use something like this :

Func ProcessWaitCloseEx($iPID)
  While ProcessExists($iPID) And Sleep(10)
  WEnd
EndFunc

 

ps Another option is to read only once the answer from the "whoami" process, you could do it on the initial load or have an array containing the answers once read.
pps : If you decide to go with the initial load approach, then you could delegate the reading to another process (then IPC or multi-thread would be helpful) while you prepare your GUI and show it to the user...

Edited by Nine
Posted

Another thing with your code.  While playing with it I noticed that sometimes a small + (copy sign) was appearing.

It seems that your WM_NOTIFY2 winproc doesn't like much staying in the function too long.  By using a dummy control, and sending the responsibility to get and show the registry read and the run is solving the issue and accelerate the display...

 

...
Global $idDummy = GUICtrlCreateDummy()
...
Case $MSG = $idDummy
        GetMsstyles()
        IsMsstylesPatched()
...
Case $LVN_ITEMCHANGED
                    Local $tInfo = DllStructCreate($tagNMLISTVIEW, $ilParam)
                    Local $iItem = DllStructGetData($tInfo, "Item")
                    $iMsstyles = $aFileList[$iItem][1]
                    GUICtrlSendToDummy($idDummy)

 

Posted
  On 3/30/2025 at 2:17 PM, Nine said:

Which is quite slow.  You could use something like this :

Func ProcessWaitCloseEx($iPID)
  While ProcessExists($iPID) And Sleep(10)
  WEnd
EndFunc

 

Expand  

This is a very good idea. I can’t test until later in the day, but I imagine this might be enough of a difference and keep things simple.

  On 3/30/2025 at 3:51 PM, Nine said:

By using a dummy control, and sending the responsibility to get and show the registry read and the run is solving the issue and accelerate the display.

Expand  

And with this further improving overall performance, that is great news. I will test it all later and see.

I really prefer to keep it simple and avoid IPC and extra binary unless I really have to.

  On 3/30/2025 at 2:17 PM, Nine said:

Maybe there is a dll that could return your request, that way you would get the answer instantly.

Expand  

It is interesting that you mention this. The SecureUxTheme actually does provide a library DLL with well documented options for obtaining theme info, applying themes, etc.

But the problem with my lack of experience is that I have no idea even where to begin with constructing DllCall and things like that in AutoIt. This would certainly be the most performant method.

  On 3/30/2025 at 4:23 PM, argumentum said:

..using your script I figure that you may want to prefetch the info. It does not change that often.

Expand  

Yes, true. It would not change often at all. Prefetch would be smart. I do have an array to store stuff in as well. Great idea.

Posted
  On 3/30/2025 at 2:17 PM, Nine said:

initial load

Expand  

==

  On 3/30/2025 at 4:23 PM, argumentum said:

prefetch

Expand  

:)

A final note on your WM_NOTIFY, you get to have 3 notifications (except for the very first one), 2 for the previous selected item and 1 for the newly selected item.  So there is 2 useless calls to the "whoami" process, which slow down a lot your listview.  By having a static variable that check if the item has effectively changed, you would accelerate by 66% the performance of your GUI...

Posted
  On 3/30/2025 at 4:52 PM, Nine said:

By having a static variable that check if the item has effectively changed, you would accelerate by 66% the performance of your GUI...

Expand  

That is a significant find, thank you. I tested what you said with a simple ConsoleWrite and it was certainly doing 3 each time. So I will make the function discard values that are equal to previous so that it doesn’t run 3 times like that.

 

Posted

@Nine I finally got a chance to sit down and implement your suggestions. Your custom ProcessWaitCloseEx function made a dramatic difference. That alone made me quite happy with how it's functioning now. I also filtered out the duplicates from WM_NOTIFY so that the command only runs 1 time now and that smoothed out the GUI performance even more.

The only thing that did not work for some reason was the dummy control. I get the response back from GetMsstyles() but not from IsMsstylesPatched() even though they are both there. But I am happy with the way everything is performing now so it's not too much of a concern getting the dummy control to work.

By the way, I really appreciate your time and your expertise on this. It really made a significant difference and all without the need for any multi-process IPC and so on.

Posted
#include <GUIConstantsEx.au3>
Global $g_idLabel = 0
Example()
Func Example()
    GUICreate("Busy or not, here I go...", 400, 200)
    $g_idLabel = GUICtrlCreateLabel("nothing", 10, 10, 100)
    GUISetState(@SW_SHOW)
    AdlibRegister(flipit, 2000)
    While GUIGetMsg() <> $GUI_EVENT_CLOSE
    WEnd
    GUIDelete()
EndFunc   ;==>Example

Func flipit()
    Local Static $bBusy = False
    $bBusy = Not $bBusy
    GUICtrlSetData($g_idLabel, $bBusy ? "busy" : "nothing")
    GUISetCursor($bBusy ? 1 : 2, 1)
EndFunc   ;==>flipit

..to tell the user that the script is doing something.

Follow the link to my code contribution ( and other things too ).
FAQ - Please Read Before Posting.
autoit_scripter_blue_userbar.png

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