I have a simple 'Working' form that runs on its own thread to keep the user informed that the application hasn't died during long running operations. In order to get the working form to update I had to insert a DoEvents()
call.
I'm curious, will this only pump messages for the current thread I'm in, or will it do it for the whole application? I would prefer that the main window stay unresponsive till the operation finishes, so I'm curious as to the behavior. Below is the code for the working form.
Just to be clear, I'm fine with the code I have, but I would like to know how DoEvents()
behaves with threads.
Public Class frmWorking
''' <summary>
''' Creates and starts a new thread to handle the Working Dialog
''' </summary>
''' <returns>The thread of the Working dialog.</returns>
''' <remarks></remarks>
Public Shared Function StartWait() As WorkingFromToken
Dim th As New Threading.Thread(AddressOf ShowWait)
Dim token As New WorkingFromToken
th.Start(token)
Return token
End Function
Private Shared Sub ShowWait(token As WorkingFromToken)
Dim frm As New frmWorking
Try
frm.Show()
Do
If frm.txtWait.Text.Length > 45 Then
frm.txtWait.Text = "Working"
Else
frm.txtWait.Text &= "."
End If
Windows.Forms.Application.DoEvents()
Threading.Thread.Sleep(250)
Loop While token.Running
frm.Hide()
Catch ex As Threading.ThreadAbortException
Threading.Thread.ResetAbort()
frm.Hide()
Return
End Try
End Sub
End Class
DoEvents
will only pump the current UI thread.However, I do not recommend your approach.
Instead, you should do your work on a background thread, and show a modal progress form on the UI thread and update it using
BeginInvoke
or aBackgroundWorker
.DoEvents
will only effect the thread from which it is called. It will dequeue all windows messages posted to that thread and dispatch them accordingly. After all messages have been dispatched it will return back to the caller.I have a couple of other observations about your code though.
DoEvents
repeatedly in a loop. It would be better to just callApplication.Run
to initiate a full blown message loop.ThreadAbortException
is pointless in most situation. If you ever get this exception then it is possible (perhaps even likely) that the state of the entire AppDomain has been corrupted. It is better to tear down the application domain than to try to gracefully deal with it. This is because the exception could be injected at any point during the execution of the thread and those injection points could be in the middle or a write, a lengthy operation, or otherwise some unsafe point.Thread.Abort
to terminate another thread. There are many too many things that can go wrong. It is better to cause the thread to end gracefully using safer mechanisms.