By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,887 Members | 1,214 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,887 IT Pros & Developers. It's quick & easy.

Unhandled Exceptions and Multi-Threading

P: n/a
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
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.