Best way to show an alert from a thread


I want to show an alert dialog from a thread (for example when an error occur).
What is the best way to do that ?

I 've done that way :
My thread subclass have a method named “ShowError” that activate a timer :

[code] timer.Period = 10
timer.Mode = timer.ModeSingle

self.isWaiting = True
While self.isWaiting

When this timer action fire, it call another method of my thread subclass “ErrorTimerAction” that raise a custom event “Error” :

RaiseEvent Error self.isWaiting = False

My thread is added in a window. In the Error event of this instance of my thread, I show the alert dialog.

Is it the right way or must I change ? Can I use app.YieldToNextThread for that ?

Thank you

I use CallMethodOnMainThreadMBS from the Monkeybread plugins.

On Window1 I have a method like this:

Sub MsgBoxMain(value1 As Variant) MsgBox(value1) End Sub

In a thread I have code similar to this:

If imDatabase.Error Then Dim msg As String = "ERROR : " + imDatabase.ErrorMessage Call CallMethodOnMainThreadMBS (Window1, "MsgBoxMain", msg) End If

app.YieldToNextThread should not be needed.
Of course you can do a me.sleep(5) to put thread on sleep and give main thread a chance to show dialog.

I use a loop with app.YieldToNextThread in order to stop temporary the code execution, show the dialog and wait the user answer. Next, quitting the loop when self.isWaiting is False, I want to continue using the value of the user’s answer.
I think I can not achieve that with me.sleep.

Ah, yes, Christian, I see what your are saying. I’ve misunderstood the sleep method.
Do you say it’s better to use Thread.sleep then app.YieldToNextThread ?

Depends on what you do…

I simply want my thread pause and wait the answer given by the user via my dialog and next, I want my thread continue in one or other direction according to this answer.
Is there a CPU usage, performance or stability advantage using Thread.sleep instead of app.YieldToNextThread ?

I have a second question : Currently, the timer action raise an event in witch the dialog is shown. Can I show the dialog directly in the timer action ? Is it allowed/stable ? In other words, does the Timer action fire in the custom thread or in the main thread. If this is in the custom thread, I suppose I can not, since we are not allowed to update the UI there.

Timers always fire in the main thread. Sleep is probably better in this case than Yield, as yield my end up returning immediately to your thread.

You can use suspend/resume:
In a timersubclass (we’ll call it messageTimer) we have 2 properties “mCaller as weakref” and “mMessage as String” and a method “ShowMessage”.

Sub ShowMessage(message As String) mMessage=message mCaller=new WeakRef(app.CurrentThread) me.mode=1 if mCaller.Value<>nil then thread(mCaller.Value).Suspend End Sub

and in the Action Event…

Sub Action() MsgBox(mMessage) if mCaller.Value<>nil then Thread(mCaller.Value).Resume mCaller=nil End Sub

then it can be called like so.

dim mErrorTimer as new ErrorTimer mErrorTimer.ShowMessage "An error ocurred" //the thread will suspend here until the timer resumes it.

This approach also works well to get feedback from the user in the middle of a thread. You could add a result property to the timer subclass and set that from a dialog (rather than using msgbox), then the thread can look at the messageTimer.result to decide what to do next.

should be

dim mMessageTimer as new messageTimer mMessageTimer.ShowMessage "An error ocurred"

Hello Jim,
Your solution is simple, clear and, I think, more natural . I will go that way.
Thank you. And thank you all that help me find the best way.