I’m having an issue with the Task class from UIThreadingWithTask example.
I’m calling UpdateUI in the Run event many times, for sample in a file download, I have noticed that in Windows this will raise a RuntimeException with message: “Current process has used maximum number of manipulators allowed by the object system in Windows administrator” (translated).
It can be reproduced using the mentioned UIThreadingWithTask example by changing Run code to:
[code]Dim progressValue As Integer
While progressValue < 100
progressValue = progressValue + 1
// Do some long-running process
LongRunningMethod
// Call UpdateUI with any parameters you need. This calls the UpdateUI event handler
// where you can directly access any UI controls on the Window.
// This specifies simple parameters using a Pair
// You can also pass values using a Dictionary
Dim n as integer = 0
while n < 1000 //in a real runtime this may happen while downloading a file if only bytes received are used to update
Me.UpdateUI(“UIProgress”:progressValue)
n = n + 1
wend
Wend
[/code]
In Mac it works fine and it has worked until now in Windows, seems last OS updates are different.
While debugging I have found that InternalDispatchEvents is never called in Windows once Run has started.
I know I can check the progress value and minimize use of UpdateUI but, is there another solution? Or do I have to use the Timer update option?
In Task.InternalPushEvent, there is code to make sure the timer is running when a new UpdateUI request comes through. It looks like this code is starting a new timer each time through and reaching a limit on Windows. I’m not sure if this is a bug with the Windows timer, but it looks like you can avoid it.
I didn’t worried about timer, being local and unique to the Task I thought that changing mode or period wouldn’t start a new Timer but it seems in last Windows versions it does.
In my app under MacOS, if I include the conditional timer period and mode setting the UI is refreshed only once or not at all, event though I can see that I’m calling UpdateUI repeatedly. If I execute those lines, it works all the time.
I dont remember exactly in which macOS version 10.10? 10.11? Apple changed something in their NSView redraw handling so that an invalidated or updated control simply does not get enough time to redraw and the app returns to tight loops without visual feedback. Infamous are folderitem dialogues closing with a delay of several seconds if you dont give the system time to update its UI.
I often find myself refactoring methods into several smaller ones, calling each other with a very short Xojo.core.Timer.CallLater delay to work around these framework changes. It is interesting anyway that the absence of the condition above allows the system to redraw while the If clause does not. What happens if you yield to other threads before the End If on macOS?
And did someone create a feedback entry to investigate why Windows creates new timers when it should not?
I’m running 10.12 right now. The UI update is a canvas redraw. Sorry, no time to experiment with yield times, I just need it to work, and it does (for the moment) if I do the timer period and mode updates. The ultimate target is Windows, I just do my coding on Mac.