Application.ThreadException Evento
Definição
Importante
Algumas informações dizem respeito a um produto pré-lançado que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.
Ocorre quando uma exceção de thread untraped é lançada.
public:
static event System::Threading::ThreadExceptionEventHandler ^ ThreadException;
public static event System.Threading.ThreadExceptionEventHandler ThreadException;
member this.ThreadException : System.Threading.ThreadExceptionEventHandler
Public Shared Custom Event ThreadException As ThreadExceptionEventHandler
Tipo de Evento
Exemplos
O exemplo de código seguinte define os gestores de eventos para exceções que ocorrem em threads do Windows Forms e exceções que ocorrem noutros threads. Define SetUnhandledExceptionMode para que todas as exceções sejam tratadas pela aplicação, independentemente das definições no ficheiro de configuração do utilizador da aplicação. Utiliza o ThreadException evento para tratar exceções de threads UI e o UnhandledException evento para tratar exceções de threads não UI. Como UnhandledException não pode impedir a terminação de uma aplicação, o exemplo simplesmente regista o erro no registo de eventos da aplicação antes da terminação.
Este exemplo assume que definiu dois Button controlos, button1 e button2, na sua Form turma.
// Creates a class to throw the error.
public:
ref class ErrorHandler: public System::Windows::Forms::Form
{
// Inserts the code to create a form with a button.
// Programs the button to throw an exception when clicked.
private:
void button1_Click( Object^ /*sender*/, System::EventArgs^ /*e*/ )
{
throw gcnew ArgumentException( "The parameter was invalid" );
}
public:
static void Main()
{
// Creates an instance of the methods that will handle the exception.
CustomExceptionHandler ^ eh = gcnew CustomExceptionHandler;
// Adds the event handler to the event.
Application::ThreadException += gcnew ThreadExceptionEventHandler( eh, &Form1::CustomExceptionHandler::OnThreadException );
// Runs the application.
Application::Run( gcnew ErrorHandler );
}
};
// Creates a class to handle the exception event.
internal:
ref class CustomExceptionHandler
{
// Handles the exception event.
public:
void OnThreadException( Object^ /*sender*/, ThreadExceptionEventArgs^ t )
{
System::Windows::Forms::DialogResult result = ::DialogResult::Cancel;
try
{
result = this->ShowThreadExceptionDialog( t->Exception );
}
catch ( Exception^ )
{
try
{
MessageBox::Show( "Fatal Error", "Fatal Error", MessageBoxButtons::AbortRetryIgnore, MessageBoxIcon::Stop );
}
finally
{
Application::Exit();
}
}
// Exits the program when the user clicks Abort.
if ( result == ::DialogResult::Abort )
{
Application::Exit();
}
}
// Creates the error message and displays it.
private:
System::Windows::Forms::DialogResult ShowThreadExceptionDialog( Exception^ e )
{
String^ errorMsg = "An error occurred please contact the adminstrator with the following information:\n\n";
errorMsg = String::Concat( errorMsg, e->Message, "\n\nStack Trace:\n", e->StackTrace );
return MessageBox::Show( errorMsg, "Application Error", MessageBoxButtons::AbortRetryIgnore, MessageBoxIcon::Stop );
}
};
Thread newThread = null;
// Starts the application.
public static void Main(string[] args)
{
// Add the event handler for handling UI thread exceptions to the event.
Application.ThreadException += new ThreadExceptionEventHandler(ErrorHandlerForm.Form1_UIThreadException);
// Set the unhandled exception mode to force all Windows Forms errors to go through
// our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
// Add the event handler for handling non-UI thread exceptions to the event.
AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
// Runs the application.
Application.Run(new ErrorHandlerForm());
}
// Programs the button to throw an exception when clicked.
private void button1_Click(object sender, System.EventArgs e)
{
throw new ArgumentException("The parameter was invalid");
}
// Start a new thread, separate from Windows Forms, that will throw an exception.
private void button2_Click(object sender, System.EventArgs e)
{
ThreadStart newThreadStart = new ThreadStart(newThread_Execute);
newThread = new Thread(newThreadStart);
newThread.Start();
}
// The thread we start up to demonstrate non-UI exception handling.
void newThread_Execute()
{
throw new Exception("The method or operation is not implemented.");
}
// Handle the UI exceptions by showing a dialog box, and asking the user whether
// or not they wish to abort execution.
private static void Form1_UIThreadException(object sender, ThreadExceptionEventArgs t)
{
DialogResult result = DialogResult.Cancel;
try
{
result = ShowThreadExceptionDialog("Windows Forms Error", t.Exception);
}
catch
{
try
{
MessageBox.Show("Fatal Windows Forms Error",
"Fatal Windows Forms Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop);
}
finally
{
Application.Exit();
}
}
// Exits the program when the user clicks Abort.
if (result == DialogResult.Abort)
Application.Exit();
}
// Handle the UI exceptions by showing a dialog box, and asking the user whether
// or not they wish to abort execution.
// NOTE: This exception cannot be kept from terminating the application - it can only
// log the event, and inform the user about it.
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
try
{
Exception ex = (Exception)e.ExceptionObject;
string errorMsg = "An application error occurred. Please contact the adminstrator " +
"with the following information:\n\n";
// Since we can't prevent the app from terminating, log this to the event log.
if (!EventLog.SourceExists("ThreadException"))
{
EventLog.CreateEventSource("ThreadException", "Application");
}
// Create an EventLog instance and assign its source.
EventLog myLog = new EventLog();
myLog.Source = "ThreadException";
myLog.WriteEntry(errorMsg + ex.Message + "\n\nStack Trace:\n" + ex.StackTrace);
}
catch (Exception exc)
{
try
{
MessageBox.Show("Fatal Non-UI Error",
"Fatal Non-UI Error. Could not write the error to the event log. Reason: "
+ exc.Message, MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
finally
{
Application.Exit();
}
}
}
// Creates the error message and displays it.
private static DialogResult ShowThreadExceptionDialog(string title, Exception e)
{
string errorMsg = "An application error occurred. Please contact the adminstrator " +
"with the following information:\n\n";
errorMsg = errorMsg + e.Message + "\n\nStack Trace:\n" + e.StackTrace;
return MessageBox.Show(errorMsg, title, MessageBoxButtons.AbortRetryIgnore,
MessageBoxIcon.Stop);
}
Private newThread As Thread = Nothing
' Starts the application.
<SecurityPermission(SecurityAction.Demand, Flags:=SecurityPermissionFlag.ControlAppDomain)> _
Public Shared Sub Main()
' Add the event handler for handling UI thread exceptions to the event.
AddHandler Application.ThreadException, AddressOf ErrorHandlerForm.Form1_UIThreadException
' Set the unhandled exception mode to force all Windows Forms errors to go through
' our handler.
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException)
' Add the event handler for handling non-UI thread exceptions to the event.
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException
' Runs the application.
Application.Run(New ErrorHandlerForm())
End Sub
' Programs the button to throw an exception when clicked.
Private Sub button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button1.Click
Throw New ArgumentException("The parameter was invalid")
End Sub
' Start a new thread, separate from Windows Forms, that will throw an exception.
Private Sub button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button2.Click
Dim newThreadStart As New ThreadStart(AddressOf newThread_Execute)
newThread = New Thread(newThreadStart)
newThread.Start()
End Sub
' The thread we start up to demonstrate non-UI exception handling.
Sub newThread_Execute()
Throw New Exception("The method or operation is not implemented.")
End Sub
' Handle the UI exceptions by showing a dialog box, and asking the user whether
' or not they wish to abort execution.
Private Shared Sub Form1_UIThreadException(ByVal sender As Object, ByVal t As ThreadExceptionEventArgs)
Dim result As System.Windows.Forms.DialogResult = _
System.Windows.Forms.DialogResult.Cancel
Try
result = ShowThreadExceptionDialog("Windows Forms Error", t.Exception)
Catch
Try
MessageBox.Show("Fatal Windows Forms Error", _
"Fatal Windows Forms Error", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop)
Finally
Application.Exit()
End Try
End Try
' Exits the program when the user clicks Abort.
If result = DialogResult.Abort Then
Application.Exit()
End If
End Sub
' Handle the UI exceptions by showing a dialog box, and asking the user whether
' or not they wish to abort execution.
' NOTE: This exception cannot be kept from terminating the application - it can only
' log the event, and inform the user about it.
Private Shared Sub CurrentDomain_UnhandledException(ByVal sender As Object, _
ByVal e As UnhandledExceptionEventArgs)
Try
Dim ex As Exception = CType(e.ExceptionObject, Exception)
Dim errorMsg As String = "An application error occurred. Please contact the adminstrator " & _
"with the following information:" & ControlChars.Lf & ControlChars.Lf
' Since we can't prevent the app from terminating, log this to the event log.
If (Not EventLog.SourceExists("ThreadException")) Then
EventLog.CreateEventSource("ThreadException", "Application")
End If
' Create an EventLog instance and assign its source.
Dim myLog As New EventLog()
myLog.Source = "ThreadException"
myLog.WriteEntry((errorMsg + ex.Message & ControlChars.Lf & ControlChars.Lf & _
"Stack Trace:" & ControlChars.Lf & ex.StackTrace))
Catch exc As Exception
Try
MessageBox.Show("Fatal Non-UI Error", "Fatal Non-UI Error. Could not write the error to the event log. " & _
"Reason: " & exc.Message, MessageBoxButtons.OK, MessageBoxIcon.Stop)
Finally
Application.Exit()
End Try
End Try
End Sub
' Creates the error message and displays it.
Private Shared Function ShowThreadExceptionDialog(ByVal title As String, ByVal e As Exception) As DialogResult
Dim errorMsg As String = "An application error occurred. Please contact the adminstrator " & _
"with the following information:" & ControlChars.Lf & ControlChars.Lf
errorMsg = errorMsg & e.Message & ControlChars.Lf & _
ControlChars.Lf & "Stack Trace:" & ControlChars.Lf & e.StackTrace
Return MessageBox.Show(errorMsg, title, MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Stop)
End Function
Observações
Este evento permite que a sua aplicação Windows Forms trate exceções que de outra forma não seriam tratadas e que ocorrem em threads do Windows Forms. Anexe o seu gestor de eventos ao ThreadException evento para lidar com estas exceções, o que deixará a sua candidatura num estado desconhecido. Sempre que possível, as exceções devem ser tratadas por um bloco estruturado de tratamento de exceções.
Pode alterar se este callback é usado para exceções de thread Windows Forms não tratadas definindo SetUnhandledExceptionMode. Para detetar exceções que ocorrem em threads que não foram criados e não pertencem a Windows Forms, use o handler de eventos UnhandledException.
Note
Para garantir que nenhuma ativação deste evento é perdida, deve ligar um responsável antes de ligar Application.Run.
Note
Apenas um manipulador pode ser associado a este evento. Se forem adicionados vários handlers, apenas o handler adicionado mais recentemente será chamado numa exceção não tratada.
Caution
Como este é um evento estático, deve separar os seus gestores de eventos quando a sua aplicação é eliminada, caso contrário ocorrerão fugas de memória.