hey

I'm writing a quick example of multi threading for someone and it got me thinking about how everyone else deals with exceptions raised on a background thread, as I kind of just made up my own way of handling them and getting the error message details back to the UI thread to be displayed to the user. Perhaps it is pretty much the same way as most people do it but I'm just curious if other people do it completely differently.

Lets say we have a program that has a button on it and when clicked that button disables most of the UI and shows a progress bar etc, then creates a new thread and gets that to run some long running operation (so that the GUI doesn't freeze while this long blocking operation is being run). If the long running operation throws an exception then we want to show that error message to the user, but even if it doesn't then we need to re-enable the UI and hide the progress bar etc to show that the operation has completed (and perhaps we need to return some results from this operation to be displayed in the UI). So this is how I would do that (the example is from WPF but it would be very similar in WinForms) :

vb.net Code:
  1. Class MainWindow
  2.  
  3.     Private Sub BtnSearch_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles BtnSearch.Click
  4.         'Normally I would disable the buttons on the UI and show the progress bar etc here as well
  5.         Dim BgThread As New System.Threading.Thread(AddressOf DoSomeWork)
  6.         BgThread.IsBackground = True
  7.         BgThread.Start()
  8.     End Sub
  9.  
  10.     Private Sub DoSomeWork()
  11.         Dim ErrorMessage As String = String.Empty
  12.         Dim Results As List(Of SearchResultItem)
  13.         Try
  14.             Results = SomeLongRunningOperation()
  15.         Catch ex As Exception
  16.             ErrorMessage = ex.Message
  17.         Finally
  18.             SearchFinished(ErrorMessage, Results)
  19.         End Try
  20.     End Sub
  21.  
  22.     Private Sub SearchFinished(ErrorMessage As String, Results As List(Of SearchResultItem))
  23.         If Me.Dispatcher.CheckAccess Then
  24.             'Normally I would re enable the UI and hide the progress bar here as well
  25.             If String.IsNullOrEmpty(ErrorMessage) Then
  26.                 MessageBox.Show("Operation completed successfully - " & Results.Count & " results found")
  27.             Else
  28.                 MessageBox.Show("Error encountered: " & ErrorMessage)
  29.             End If
  30.         Else
  31.             Me.Dispatcher.Invoke(New Action(Of String, List(Of SearchResultItem))(AddressOf SearchFinished), ErrorMessage, Results)
  32.         End If
  33.     End Sub
  34.  
  35. End Class

So basically if the operation on the background thread throws an exception then that gets stored in the ErrorMessage variable which will always get passed in to the method that is always called before the background thread terminates, and that is then used to determine if an exception occurred or not. Of course it should also check to see if the results list was Nothing but I left that out for the sake of keeping this example short and to the point. I've never had any problems with using this technique at all, but like I said I'm just curious to see if other people do something similar or if you use events or callbacks instead.