Asynchronous Error Handling (DotNet)

Soldato
Joined
5 Mar 2003
Posts
10,771
Location
Nottingham
Hi all,
Just wondering if there is a "standard" to handle the following situation.

I have a GUI which calls SQL queries in another thread. These queries can run for a long time and possibly time out. The problem I have is that when there is an exception the whole app crashes (as the exception isnt being handled in the new thread). Now it's fairly simple to correct this issue, however I want the user (i.e. GUI) to be notified of the error and display it to the users.

Now to my knowledge there are a few options:
  • Events - The event would return the result and also some args to specify the state etc (complete, cancelled, error).
  • Async Delegates - This is my current implementation and just returns the result. To make this handle errors correctly, I would need to wrap the result and any error information into a "bigger" class.
  • Polling - The "worker" thread could actually not terminate and the "main" thread could just poll states on the worker thread to see if it has a result and if not check for state.

My idea situation would be one where the worker thread could put the exception on the main thread before exiting, however I dont think this exists (exceptions are stack-bound objects. Since every thread has its
own stack, an exception thrown in thread A cannot suddenly appear in
thread B).

So whats the best option here? Just to be clear I know how to handle this situation but not the *best* way.

Thanks in advance!
 
Thanks for the input guys, however I have found a better solution (well at least requires me to do less work). Apparently, and I didnt know this before, if you use delegates and call begin invoke (which is how my code works at present, with async call back) - they you call EndInoke, if an exception has been raised by the worker thread, it is put on the stack of the caller thread (in this case the UI).

Obviously, if I was working on something which would be distributed I would rework the code to implement one of your solutions, as its not wise to have a worker thread bomb out for something that can occur at lot (timeouts / permission issues) but the library will only be used by this GUI.

Anywho - thanks again, and hope this post will help others in the future, as I certainly didnt know about the EndInoke / Exception stuff!
 
An example snippet of code. This is how I push the exception handling to the GUI thread. Probably should have been more clear.

Code:
private void PopulateProviderList(IAsyncResult ar)
        {
            if (ar.IsCompleted && InvokeRequired)
                Invoke(new MethodInvoker(delegate { PopulateProviderList(ar); }));
            else if (ar.IsCompleted && !InvokeRequired)
            {
                List<Provider> providerList = null;
                try
                {
                    // Get a handle on the original delegate and get the results.
                    ProviderDelegate providerDelegate = ((AsyncResult)ar).AsyncDelegate as ProviderDelegate;
                    providerList = providerDelegate.EndInvoke(ar);

                    if (providerList != null)
                    {
                        // Insert the "all providers option" and bind the results to the cbo box.
                        providerList.Insert(0, new Provider("All Providers", -1));
                        cboProviders.Enabled = true;
                    }
                    else
                        throw new ApplicationException("Provider list was null.");

                    cboProviders.DataSource = providerList;
                    Status = "Ready.";
                }
                catch (Exception ex)
                {
                    // An exception has been raised from the worker thread.
                    Status = "Could not populate provider list: " + GetOriginalErrorMessage(ex);
                    providerList = new List<Provider>();
                    providerList.Insert(0, new Provider("Error populating list.", -1));
                    cboProviders.DataSource = providerList;
                    UpdateEnabledStatus(false);
                }
            }
        }
I thought async wait actually blocks the current thread (i.e. would make the GUI unresponsive)?
 
Back
Top Bottom