Hi,
I have a shell command that blocks my progresswheel. I put my Shell command in Thread1.Run() (it’s ok ?) and a Timer.
2 questions:
1/ What should I put in the Timer? (ProgressWheel1.Visible and ProgressWheel1.Enabled ?)
2/ Where stop the ProgressWheel?
In Timer1.Action() I tried this:
if Me.RunMode = Timer.RunModes.Multiple then
ProgressWheelXPR.Visible = true
ProgressWheelXPR.Enabled = true
elseif Me.RunMode = Timer.RunModes.Off then //???
ProgressWheelXPR.Visible = false
ProgressWheelXPR.Enabled = false
end
but the ProgressWheel does not stop at the end of the process !
At the end of Thread1.run() I tried: Timer1.Mode = Timer.ModeOff
If I put the ProgressWheel.enable= false or .visible = false at the end of Thread.Run() I get a ThreadAccessUIException !
Thanks
@Ivan_Tellez
At the end of Thread1.run() I put: “Timer1.Mode = Timer.ModeOff”… to stop the Timer. Otherwise, how do you know if the thread is finished?
Putting the shell in a thread will make no difference at all to it blocking the UI. The only thing that will make it unblock the UI is to change the mode to Aynchronous.
You then start the Shell command and catch the end of the command in the Completed event. If you are expecting data back from the shell you will get that via the DataAvailable event.
You can add a shell to a window and change the mode and add events to it. Or you can subclass shell and add things there.
As far as threads go, you can use the UserInterfaceUpdate event along with the AddUserInterfaceUpdate method to interact with your controls from within a thread.
Hello,
Thank you, thanks to your information, I was able to succeed.
I just have an exception when I display an info in a Label:
“A thread attempted to manipulate a UI element. This can only be done from the main application thread.”
I think I need to use App.DoEvents(), I need to see how it works.
A somewhat more straightforward method for simple cases like just updating a progressbar or wheel is to add a timer and a property holding the progress value to your window. Update the property from the thread and in the timer’s Action event assign the property’s value to that of the progressbar/wheel.
It’s maybe less “encapsulated” than the UserInterfaceUpdate method, but easier for beginners to get their head around than parsing an array of dictionaries.
Thank you @Julia_Truchsess , but for the wheel, it’s done.
I just have an exception when I display a string in a Label, with the following message:
“A thread attempted to manipulate a UI element. This can only be done from the main application thread.”
Now, it seems to me that it is necessary to use the “UserInterfaceUpdate” event to display the content of my Label without generating an exception in my thread but apparently it also goes through a Dictionary (of which I do not really understand the interest) :
AddUserInterfaceUpdate(data As Dictionary)
or AddUserInterfaceUpdate(ParamArray data As Pair)
For the moment, it seems rather vague to me, I will do a test to see what it gives.
Every time you call AddUserInterfaceUpdate your request for an update is added to an array of dictionaries that is available to you in the event handler I mentioned upthread. The dictionary gives you the most flexible way of passing data to the event handler that you must write to do the actual updating. In my case, each dictionary has an “action” key, whose value drives a select case, and then any other keys for data items needed to do a specific update of the UI.
So the code in the event handler looks like this:
Var updateItem as new Dictionary
while (data.LastIndex>-1)
updateItem = data(0)
data.RemoveAt (0)
select case updateItem.Value("action")
case 1
// code updating the UI for this action
case 2
// etc
...
end select
wend
If your thread wants to make lots of different changes to the UI, you’ll need a way of passing a variety of parameters into the event handler. The dictionaries provide that.