views:

566

answers:

1

Hello, concurrent colleagues.

I need to be able to trap an exception that might be thrown from a background thread.

Let the code speak for itself (it is a bad code)

 public delegate bool CheckForUpdatesHandler(Uri uri);
    public class UpdatesChecker {
        public event AsyncCompletedEventHandler CheckForUpdatesAsyncCompleted;
        protected virtual void OnCheckForUpdatesAsyncCompleted(AsyncCompletedEventArgs args) {
            if (CheckForUpdatesAsyncCompleted != null)
                CheckForUpdatesAsyncCompleted(this, args);
        }

        public bool CheckForUpdates(Uri ftp) {            
            Thread.Sleep(1000);
            throw new Exception("bla");
            return true;
        }     


        public void CheckForUpdatesAsync(Uri ftp){            
            var action = new CheckForUpdatesHandler(CheckForUpdates);
            var c=action.BeginInvoke(ftp, delegate(IAsyncResult state) {
                OnCheckForUpdatesAsyncCompleted(new AsyncCompletedEventArgs(null, false, null));
            }, null);
        }    
    }
+3  A: 

With Delegate.BeginInvoke, the exception will be retrieved by calling .EndInvoke - which you must do anyway to prevent a leak.

With BackgroundWorker, it will appear on the completion event

On a vanilla Thread, an unhandled exception will tear down the process.

However, the simplest approach is: don't let it throw...

    public bool CheckForUpdates(Uri ftp) {
        try {
            Thread.Sleep(1000);
            throw new Exception("bla");
            return true;
        } catch (Exception ex) {
            // raise an event, call a method/callback, do something
        }
    }

If you currently aren't using EndInvoke, then perhaps switch to the above pattern and just use ThreadPool directly (rather than Delegate.BeginInvoke).

Marc Gravell
Thanks, Marc, you've helped me again :-)
Valentin Vasiliev