Does DoEvents effect only the current thread?
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
''' <summa开发者_开发知识库ry>
''' 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 a BackgroundWorker
.
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.
- You have basically created your own crippled version of a message loop by calling
DoEvents
repeatedly in a loop. It would be better to just callApplication.Run
to initiate a full blown message loop. - Creating a message loop on a thread other than the main UI thread is rarely a good idea. There are some weird things that occur that are hard to deal with. For example, a modal dialog box from one thread could overlap a modal dialog box from another.
- Attempting to catch a
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. - As a corollary to the point above do not use
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.
精彩评论