Cases where App.DoEvents would be used

Hey there,
I am confused as to why people would use App.DoEvents? Where it is useful in an app? And can anybody give me an example of converting code that uses App.DoEvents into an app that uses threads instead.

Thanks

In a method, I occasionally don’t pass a return until another process is completed. I create a property such as ‘isCompleted’ and set it to false… then I’ll use the following loop in the method:

[code]isCompleted = false
call SomeEvent 'this event will set isCompleted to true once it completes

do until isCompleted
app.doEvents()
loop

'put other method processes here
return variable[/code]

[quote=75271:@Oliver Scott-Brown]Hey there,
I am confused as to why people would use App.DoEvents? Where it is useful in an app? And can anybody give me an example of converting code that uses App.DoEvents into an app that uses threads instead.

Thanks[/quote]

App.DoEvents is used to keep the UI responsive during time consuming operations that would otherwise hang the app.

Such an example would be :

while 0<>1 App.DoEvents wend

Without App.DoEvents, the app hangs forever and you cannot even quit.

The way to safely get the same result is to add a thread to the app. For instance CustomThread, and add to its run event the code

while 0<>1 wend

Then add a subclass to the main window CustomThread1, and add to the window Open :

CustomThread1.Run

The endless loop will execute fine but it will not hang the UI.

People who use App.DoEvents probably find it heavy to have to move their code to a thread, and to manage communication between the thread and the main thread. Indeed, adding a single line to a work intensive loop is a lot simpler than moving it to a thread. If the risk is to have the program do a dirty crash, though, I’ll rather use a thread.

Of course, an endless loop such as above has no other purpose than to demonstrate :wink:

Here’s an example:

I have one app that does a lot of disc intensive work inside a large x,y loop

I don’t want the user to be changing data while that is happening, so I believe I can’t throw it out into a thread.
I don’t want the app to look unresponsive to Windows either, so every now and then, I use app.doevents so that it has a chance to paint the screen, and update a progress bar.

I have already disabled menu items and controls that would affect data: the user can’t cause re-entrant code to occur.

If I put this in a thread, I can’t update the UI,so the progress bar is useless.
And the very data that is being saved could be getting changed while it is being saved: THATS what I call bad.

Now, I can hear people lining up to say ‘you can do it in a thread if you do A, B, C, and watch out for D’
But it works flawlessly with one line of code right now.

I admit , its a habit that came with me from VB. (Never caused me any trouble there , either)
I can’t see a reason to lose it, and the other thread asking for it to be removed has sadly degraded into a religious argument.

[quote=75271:@Oliver Scott-Brown]Hey there,
I am confused as to why people would use App.DoEvents? Where it is useful in an app?
[/quote]
There are so precious few where it IS useful & safe that the general answer is “They’re not - don’t do this”
And that is almost without exception the best answer

IF you think you might need it then think twice, add a thread & run that & check for the threads running to completion and get the result from the thread instead

Instead of erics

isCompleted = false
call SomeEvent 'this event will set isCompleted to true once it completes

do until isCompleted
app.doEvents()
loop

'put other method processes here
return variable

create a thread object that will do the same computation

dim c as new computeThread 
c.Run
while c.State = Thread.Running
app.yieldtonextthread
loop

'put other method processes here
return variable

Most times we run into it being used by folks who got into the habit of using it in VB - where it’s semantics & behavior were VERY different and reasonably safe

[quote=75303:@Jeff Tullin]
I admit , its a habit that came with me from VB. (Never caused me any trouble there , either)
I can’t see a reason to lose it, and the other thread asking for it to be removed has sadly degraded into a religious argument.[/quote]
This is the most common cause - VBer’s using it as they would have in VB assuming its the same thing and its not.
Lose it - because it’s unsafe - not religion - its bad code and it will bite you one day.

Locking the UI so a person can’t alter data while you’re doing something long running has nothing to do with use doevents or use a thread. You can certainly have a UI that makes it impossible for the user to alter data when running a thread.

One big exception is console/service apps, in which case it is both safe (since the event loop is your own) and often necessary.

Norm, I think you screwed up your example. Your fixed code still uses DoEvents. I think you meant YieldToNextThread.

But, the even example given isn’t a good one. If the computation takes long enough to require a thread, it probably should be refactored to be event-driven rather than synchronous.

Yup
Damn fingers

[quote=75310:@Thom McGrath]
But, the even example given isn’t a good one. If the computation takes long enough to require a thread, it probably should be refactored to be event-driven rather than synchronous.[/quote]
Just lifted Erics “where I use DoEvents example”

Thom, people who are already afraid of threads will start squealing :wink: LOL

I know. I was just adding information for the posterity of the thread.

Granted its a simple example but still not one where DoEvents is terribly good
In a thread I do not have to create the extra property for “is completed”
I just see if the thread is done & wait until it is which is EXACTLY what Eric’s case wanted - Stay responsive while the computation ran and then move on when it is.

Eric: the code definitely needs to be refactored to embrace an asynchronous, event driven model.

Jeff: you’re fooling yourself if you think that DoEvents will protect your data while a thread won’t. DoEvents exposes the same danger to your data as a thread. If you’ve managed to protect the data from change while using DoEvents, it would be just as safe using a thread.

[quote=75271:@Oliver Scott-Brown]Hey there,
I am confused as to why people would use App.DoEvents? Where it is useful in an app?
[/quote]
It’s not useful anywhere in a GUI app.

[quote]And can anybody give me an example of converting code that uses App.DoEvents into an app that uses threads instead.
[/quote]
Say you have a button with code in its Action event:

while DoingSomeLongProcess
    DoABunchOfStuff
    app.DoEvents
wend

Copy the entire contents of the Action event and copy it into an new method

Sub DoTheLongProcess
   while DoingSomeLongProcess
       DoABunchOfStuff
   wend
End Sub

Then drag a thread onto the window and call your method from the Run event. Replace the button’s Action event code with Thread1.Run. Not much to it.

I’d go further & say it’ll likely bite you if you do use it in a GUI App. The only place I’ll ever use it is in the Run even of a console or service project, but having said that it is incredibly useful - have a look at

https://dl.dropboxusercontent.com/u/18858366/CleanTemp.xojo_binary_project

where I put my app to sleep for nearly a half day, and then a quarter, eighth etc. This app running as a windows service will use no measurable resources until the last minute then absolutely minimal until it starts work and will revert to nothing after each run cycle.

I am using DoEvents in iClip, which is a LSUIElement (background-only) Mac app, in places where I need to give other apps extra time to process changes to the clipboard. Turning that into an event driven process would be a lot of work, because of the need to maintain the state (these DoEvents calls are in quite deep code paths), and make the code flow quite hard to follow, too.

Another case in iClip is where I use DoEvents during a mousedown/drag operation in order to allow an HTML view to update its contents during this operation. couldn’t figure out how to get this working otherwise.

Then there is a “deliver promised file” callback I get from the system (set by the PasteboardSetPromiseKeeper function) - I need to use DoEvents before returning or the Finder may act up.

So, if Xojo would remove DoEvents, I’d probably just revert to implementing a replacement call with declares because it works well as I’ve implemented it and would not want to risk refactoring large parts of this code just because others think it’s “bad style”.

GOTO = others think it’s “bad style”
DoEvents = dangerous
dangerous <> “bad style”

This is turning into a religous/political style argument (in my opinion).

Even Norman admitted [quote]There are so precious few where it IS useful[/quote] inferring that it does have a place albeit a small one.

Perhaps it is dangerous, perhaps there are better ways to factor some code, but isn’t that up to the developer to decide what does and does not work for a particular situation? Is it not the duty of vendor to provide detailed information about what a command specifically does (nobody answered by question on the other thread), so that the developer can make the decision?

I am still of the understanding that it does the samething in Xojo and it does in VB, and that is yield the main thread to the immediate processing of stacked messages… and I see no danger in that. But if it does not do that, or does more/less than that… I do so wish someone would explain. Until then…all I keep hearing is “Have FAITH! Ye verily it is a bad thing”

Yes I did.

[quote=75411:@Thomas Tempelmann]
So, if Xojo would remove DoEvents, I’d probably just revert to implementing a replacement call with declares because it works well as I’ve implemented it and would not want to risk refactoring large parts of this code just because others think it’s “bad style”.[/quote]

This would be safer since it would NOT cause Xojo’s event loop to run which is the primary source of problems.