469,913 Members | 2,648 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,913 developers. It's quick & easy.

Unhandled Exceptions and Multi-Threading

I recently read Jason Clark's excellent article on Unhandled Exceptions
(http://msdn.microsoft.com/msdnmag/is...T/default.aspx) and have
attempted to incorporate the features he talks about in a new application I'm
writing. However, when I try to use ThreadStart to do some work in a separate
thread from my GUI, the methods Jason described don't seem to catch the
exception. Take the following source code:

Public Class UnhandledExceptions

Public Shared Sub Main()

Try
SubMain()
Catch lobjException As Exception
HandleException(lobjException)
End Try

End Sub

Private Shared Sub SubMain()

'ATTACH EVENT HANDLER FOR CLR UNHANDLED EXCEPTIONS
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf
AppDomain_UnhandledException

'ATTACH THE EVENT HANDLER FOR UNHANDLED WINDOWS FORMS EXCEPTIONS
AddHandler Application.ThreadException, AddressOf
Application_ThreadException

Application.EnableVisualStyles()
Application.Run(New MainForm)

End Sub

Private Shared Sub HandleException(ByVal vobjException As Exception)

MessageBox.Show(vobjException.Message, "Unhandled Exception Caught",
MessageBoxButtons.OK, MessageBoxIcon.Stop)

Environment.Exit(1)

End Sub

Private Shared Sub AppDomain_UnhandledException(ByVal sender As Object,
ByVal e As UnhandledExceptionEventArgs)

Dim ue As Exception

ue = CType(e.ExceptionObject, Exception)

HandleException(ue)

End Sub

Private Shared Sub Application_ThreadException(ByVal sender As Object,
ByVal e As System.Threading.ThreadExceptionEventArgs)

HandleException(e.Exception)

End Sub

End Class
Public Class MainForm
Inherits System.Windows.Forms.Form

#Region " Windows Form Designer generated code "

Public Sub New()
MyBase.New()

'This call is required by the Windows Form Designer.
InitializeComponent()

'Add any initialization after the InitializeComponent() call

End Sub

'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub

'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer

'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
Friend WithEvents Button1 As System.Windows.Forms.Button
Friend WithEvents Button2 As System.Windows.Forms.Button
Friend WithEvents Button3 As System.Windows.Forms.Button
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
Me.Button1 = New System.Windows.Forms.Button
Me.Button2 = New System.Windows.Forms.Button
Me.Button3 = New System.Windows.Forms.Button
Me.SuspendLayout()
'
'Button1
'
Me.Button1.Location = New System.Drawing.Point(44, 24)
Me.Button1.Name = "Button1"
Me.Button1.Size = New System.Drawing.Size(204, 24)
Me.Button1.TabIndex = 0
Me.Button1.Text = "Thread"
'
'Button2
'
Me.Button2.Location = New System.Drawing.Point(44, 60)
Me.Button2.Name = "Button2"
Me.Button2.Size = New System.Drawing.Size(204, 24)
Me.Button2.TabIndex = 1
Me.Button2.Text = "ThreadPool"
'
'Button3
'
Me.Button3.Location = New System.Drawing.Point(44, 96)
Me.Button3.Name = "Button3"
Me.Button3.Size = New System.Drawing.Size(204, 24)
Me.Button3.TabIndex = 2
Me.Button3.Text = "ThreadStart"
'
'MainForm
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 273)
Me.Controls.Add(Me.Button3)
Me.Controls.Add(Me.Button2)
Me.Controls.Add(Me.Button1)
Me.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle
Me.MaximizeBox = False
Me.Name = "MainForm"
Me.StartPosition = System.Windows.Forms.FormStartPosition.CenterScree n
Me.Text = "Unhandled Exceptions"
Me.ResumeLayout(False)

End Sub

#End Region

Private Sub DoWork()

Throw New InvalidOperationException

End Sub

Private Sub DoWork(ByVal parameter As Object)

Throw New InvalidOperationException

End Sub

Private Sub WorkComplete(ByVal ar As IAsyncResult)

MessageBox.Show("Work Complete", Me.Text, MessageBoxButtons.OK,
MessageBoxIcon.Information)

End Sub

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click

Dim t As Threading.Thread

t = New Threading.Thread(AddressOf DoWork)
t.Start()

End Sub

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button2.Click

Threading.ThreadPool.QueueUserWorkItem(New
Threading.WaitCallback(AddressOf DoWork))

End Sub

Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button3.Click

Dim ts As System.Threading.ThreadStart

ts = New System.Threading.ThreadStart(AddressOf DoWork)
ts.BeginInvoke(New AsyncCallback(AddressOf WorkComplete), Nothing)

End Sub

End Class
If I click button 1 a new thread is created and it's Start method is called.
This causes DoWork to be called in a new thread, the unhandled exception is
caught and the application can be gracefully shut down (The IDE may step in
and say there's an unhandled exception but if you click Continue the
behaviour described above will occur). If I click button 2 a new work item
is added to the ThreadPool, DoWork is called in a background worker thread
and the unhandled exception is caught as before. If I click button 3 though,
the BeginInvoke method is called on a ThreadStart object causing DoWork to be
called in a new thread, but the unhandled exception seems to be swallowed and
it continues on to call the WorkComplete method.

Can anyone tell me why the third way behaves differently to the first 2? I
want to use the third way as it calls a method when it's finished which is
very useful, but I want to be able to catch any unhandled exceptions.

Thanks for taking the time to read all this and thanks in advance for your
help!

Colin
Nov 21 '05 #1
0 1734

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by terry | last post: by
4 posts views Thread by Frank | last post: by
2 posts views Thread by Bob | last post: by
3 posts views Thread by Andreas van de Sand | last post: by
reply views Thread by Jaret Brower | last post: by
1 post views Thread by Waqarahmed | last post: by
reply views Thread by Salome Sato | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.