• Upgrade your Internet Experience
  • Sign in
  • Microsoft.com
  • United States (English)
    Brasil (Português)Česká republika (Čeština)Deutschland (Deutsch)España (Español)France (Français)Italia (Italiano)Россия (Русский)대한민국 (한국어)中华人民共和国 (中文)台灣 (中文)日本 (日本語)香港特别行政區 (中文)
 
 
.NET Framework Developer Center
 
 
Home
 
 
Library
 
 
Learn
 
 
Downloads
 
 
Support
 
 
Community
 
 
Forums
 
 
 
.NET Framework Developer Center > .NET Development Forums > Windows Presentation Foundation (WPF) > Catch DispatcherUnhandledException from other Thread
Ask a questionAsk a question
Search Forums:
  • Search Windows Presentation Foundation (WPF) Forum Search Windows Presentation Foundation (WPF) Forum
  • Search All .NET Development Forums Search All .NET Development Forums
  • Search All MSDN Forums Search All MSDN Forums
 

AnswerCatch DispatcherUnhandledException from other Thread

  • Monday, January 29, 2007 3:09 PMJonas76 Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Vote As Helpful
    0

    Hi,

     

    I’m having trouble to catch the DispatcherUnhandledException from other threads than the 'main thread'. If you read the MSDN documentation  about the DispatcherUnhandledException it says:

     

     

    DispatcherUnhandledException is raised by an Application for each exception that is not handled within the AppDomain that the Application object was created in.

     

    The DispatcherUnhandledException event handler is passed a DispatcherUnhandledExceptionEventArgs argument that contains contextual information regarding the exception, including:

    • The exception (Exception).
    • The Dispatcher from which it originated (Dispatcher).

     

    This means that the exception also should be called from other threads than the main thread.

     

    If this isn't working, what's then the best way to handle global exceptions in WPF applications?

     

    Note, it works fine to catch the AppDomain.UnhandledException. But then its to late to handle the exception and the application is shut down.

     

     

    An example, raising exception from ThreadPool and from main the thread: 

    using System;

    using System.Windows;

    using System.Collections.Generic;

    using System.Text;

    using System.Windows.Threading;

    using System.Threading;

    namespace DispatcherUnhandledExceptionApplication

    {

    public class MyApplication : Application

    {

    [STAThread]

    public static void Main()

    {

    MyApplication app = new MyApplication();

    app.InitializeComponent();

    app.Run();

    }

    protected override void OnStartup(StartupEventArgs e)

    {

    base.OnStartup(e);

    Window aWindow = new Window();

    aWindow.ShowDialog();

    }

    public void InitializeComponent()

    {

    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    DispatcherUnhandledException += new System.Windows.Threading.DispatcherUnhandledExceptionEventHandler(App_DispatcherUnhandledException);

    }

    void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)

    {

    }

    void App_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)

    {

    e.Handled = true;

    System.Console.WriteLine("DispatcherUnhandledException captured!");

    }

    }

    }

     

     

     

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.Windows;

    using System.Windows.Controls;

    using System.Windows.Data;

    using System.Windows.Documents;

    using System.Windows.Input;

    using System.Windows.Media;

    using System.Windows.Media.Imaging;

    using System.Windows.Shapes;

    using System.Threading;

    using System.Windows.Threading;

     

    namespace DispatcherUnhandledExceptionApplication

    {

    /// <summary>

    /// Interaction logic for Window1.xaml

    /// </summary>

    public partial class Window : System.Windows.Window

    {

    public Window()

    {

    InitializeComponent();

    }

    void OnUIThreadButtonClicked(object sender, EventArgs e)

    {

    RaiseArgumentNullException();

    }

    void OnThreadPoolButtonClicked(object sender, EventArgs e)

    {

    ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)

    {

    try

    {

    Dispatcher.CurrentDispatcher.UnhandledException += new DispatcherUnhandledExceptionEventHandler(CurrentDispatcher_UnhandledException);

    int aDomainID = AppDomain.CurrentDomain.Id;

    Thread.CurrentThread.Name = "MyThreadPoolThread";

    Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal, new MyDlg(RaiseArgumentNullException));

    }

    catch (Exception ex)

    {

    throw ex;

    }

    finally

    {

    Dispatcher.CurrentDispatcher.UnhandledException -= new DispatcherUnhandledExceptionEventHandler(CurrentDispatcher_UnhandledException);

    }

    }));

    }

    void CurrentDispatcher_UnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)

    {

    e.Handled = false;

    }

    delegate void MyDlg();

    void RaiseArgumentNullException()

    {

    throw new ArgumentNullException();

    } 

    }

    }

     

     

     

     

     

    <Window x:Class="DispatcherUnhandledExceptionApplication.Window"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="WindowsApplication17" Height="97" Width="300"

    >

    <Grid>

    <Button Height="23" Click="OnThreadPoolButtonClicked" Margin="0,17,115,0" Name="button2" VerticalAlignment="Top" HorizontalAlignment="Right" Width="75">ThreadPool</Button>

    <Button Height="23" Click="OnUIThreadButtonClicked" HorizontalAlignment="Right" Margin="0,17,22,0" Name="button3" VerticalAlignment="Top" Width="75">UI Thread</Button>

    </Grid>

    </Window>

     

    Thanks,

    Jonas

    • ReplyReply
    • QuoteQuote
     

Answers

  • Wednesday, February 07, 2007 5:54 PMChango V. - MSFT Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     Answer
    Vote As Helpful
    0

    Jonas, the statement in the documentation is wrong. Application.Current.DispatcherUnhandledException is just shorthand for Application.Current.Dispatcher.UnhandledException, making access to the event thread-safe.

    If you want to have something like centralized exception handling, with the ability to swallow the exception, you could follow this pattern:

    1. Make the Dispatcher object of the main thread available to your worker thread. (You could either pass it as a parameter to the thread start method or just use Application.Current.Dispatcher.)
    2. Use a try-catch-finally in the worker thread. (In general, the catch block should immediately rethrow critical exceptions: OutOfMemoryException, SecurityException, SEHException, maybe also NullReferenceException.)
    3. The catch block calls mainDispatcher.Invoke(DispatcherPriority.Send, ExceptionCallback, exception).
    4. ExceptionCallback() throws the exception object passed to it. This happens on the main thread, so handlers added to Application.DispatcherUnhandledException will be invoked and can "handle" the exception.
    5. If your worker thread resumes execution, the exception was "handled."
    • ReplyReply
    • QuoteQuote
     

All Replies

  • Monday, February 12, 2007 10:45 PMMike WeinhardtMSFTUsers MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Vote As Helpful
    0

    FYI - The Application.DispatcherUnhandledException doc is being updated to be more precise. Also, I am trying to put in a couple of related samples:

    1) How to pass an exception from a background UI thread (thread with a Dispatcher) to the main UI thread
    2) How to pass an exception from a background worker thread (thread without a Dispatcher) to the main UI thread

    Thanks for the good question.

    • ReplyReply
    • QuoteQuote
     
  • Thursday, February 22, 2007 8:54 PMWill.Rogers Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Vote As Helpful
    0
    Michael,
     
    I'm in the midst of designing an error handling framework for my company's first WPF applications. If you could provide the samples you mentioned above here or to me by email it would be a great help. I am particularly concerned with how to best handle the two scenarios you mention above.
     
    Also, in the sample WPF app I'm coding in VS 2005, I'm not seeing where to hook up the DispatcherUnhandledExceptionEventHandler I've written. The expamples I've seen place this in the App's Main method, but that method resides in the App.g.cs file and is not to be hand-edited by developers.
     
    Thanks in advance for any help you (or anyone reading this) can provide.
    Will.
    • ReplyReply
    • QuoteQuote
     
  • Saturday, October 25, 2008 3:11 AMJim.Rogers Users MedalsUsers MedalsUsers MedalsUsers MedalsUsers Medals
     
    Vote As Helpful
    0

    For anyone stumbling across this thread, I've got a blog post about the implementation of this here:
    http://www.jimandkatrin.com/codeblog/2008/06/wpf-worker-thread-exceptions.html


    negative ghostrider - the pattern is full
    • ReplyReply
    • QuoteQuote
     
Need Help with Forums? (FAQ)
 
© 2009 Microsoft Corporation. All rights reserved.
Terms of Use
|
Trademarks
|
Privacy Statement