C# eventhandler中引发的WPF异常是否被吞没?
当我在eventhandler中抛出异常时,是否不调用exceptionhandler 一个简单示例的示例代码,以以下内容开始: App.xamlC# eventhandler中引发的WPF异常是否被吞没?,c#,.net,wpf,xaml,exception-handling,C#,.net,Wpf,Xaml,Exception Handling,当我在eventhandler中抛出异常时,是否不调用exceptionhandler 一个简单示例的示例代码,以以下内容开始: App.xaml <Application x:Class="WpfApplication1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
DispatcherUnhandledException="App_DispatcherUnhandledException" >
<Application.Resources/>
</Application>
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Button A" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="ButtonA_Click"/>
<Button Content="Button B" HorizontalAlignment="Left" Margin="90,10,0,0" VerticalAlignment="Top" Width="75" Click="ButtonB_Click"/>
</Grid>
</Window>
main window.xaml
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
DispatcherUnhandledException="App_DispatcherUnhandledException" >
<Application.Resources/>
</Application>
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Button A" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="ButtonA_Click"/>
<Button Content="Button B" HorizontalAlignment="Left" Margin="90,10,0,0" VerticalAlignment="Top" Width="75" Click="ButtonB_Click"/>
</Grid>
</Window>
我已经看过了,但强制32位或64位,甚至“任何CPU”都不起作用。此外,在设置任何(!)处理程序时,在事件中引发异常时,它们都不会被调用。也没用
我正在运行VS2012(在Win8上,x64),该项目使用的是.Net Framework 4.5)。我错过了什么?我疯了吗
为清楚起见:我希望显示一个messagebox(当我单击按钮时会显示),或者实际上是调用App\u dispatchernandledexception
方法。但是当我单击按钮b
时,该方法没有被调用(因此消息框没有显示)。ButtonA
和ButtonB
之间的唯一区别在于“A
”中的异常不在eventhandler中,而“B
中的异常不在eventhandler中。当然,我会在OpenFileDialog
中选择一个文件,然后单击“打开”将其选中。调试器启动并指出抛出了“不工作!?!?”异常,然后我继续执行,没有显示messagebox
另外:我是WPF的新手,这可能是问题的一部分
编辑1
以下两个zipfiles演示了确切的问题,以供参考:
(10Kb)
(10Kb)
在我的计算机上,对于上述两个项目,ButtonA会显示一个messagebox,ButtonB(在选择文件后)不会。曾经即使在启用或不启用“调试非托管代码”的情况下也不行
编辑2
因此,我在另一台机器上运行了相同的代码,并发现:在另一台机器上,调试器显示:
注意异常跨越了本机/托管边界
标题。当我尝试恢复执行(继续)时,异常会不断弹出。当调试器启动时,我的计算机显示:
…然后,当我恢复执行时,异常消失在某种黑洞中;主窗体再次显示,但什么也没有发生
这应该与此设置有关:
但是,即使重新启动VS2012和(以及项目中的bin/obj目录),打开/关闭此选项也无济于事
所以。。。我现在知道,这个例外确实与托管和非托管之间的跨边界有关。现在,我只需要找出如何解决这个问题,这样我就可以在文件OK
事件中抛出异常(这样,最终我的组件也可以抛出异常)。如果像这样连接它,您将看到它正在被处理
仍然不知道为什么它会逃避App_dispatchernhandledexception
using System.ComponentModel;
//using Microsoft.Win32;
namespace UncaughtExceptionHandler
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
//AppDomain currentDomain = AppDomain.CurrentDomain;
//currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);
InitializeComponent();
}
private void ButtonA_Click(object sender, RoutedEventArgs e)
{
throw new Exception("WTFA!?!?");
}
private void ButtonB_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
ofd.FileOk += MyCanelEventHandler;
//ofd.FileOk += (s, ce) =>
//{
// //MessageBox.Show("Throwikng Exception WTF2!?!?");
// throw new Exception("WTF2!?!?");
//};
ofd.ShowDialog();
}
static void MyCanelEventHandler(Object sender, CancelEventArgs e)
{
MessageBox.Show("MyCanelEventHandler");
throw new Exception("WTFCEH!?!?");
}
}
}
使用System.ComponentModel;
//使用Microsoft.Win32;
命名空间UncaughtExceptionHandler
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
公共主窗口()
{
//AppDomain currentDomain=AppDomain.currentDomain;
//currentDomain.UnhandledException+=新的UnhandledExceptionEventHandler(MyHandler);
初始化组件();
}
私有无效按钮单击(对象发送者,路由目标)
{
抛出新异常(“WTFA!?!?”);
}
私有无效按钮b\u单击(对象发送者,路由目标)
{
System.Windows.Forms.OpenFileDialog ofd=新建System.Windows.Forms.OpenFileDialog();
ofd.FileOk+=MyCanelEventHandler;
//ofd.FileOk+=(s,ce)=>
//{
////MessageBox.Show(“Throwikng异常WTF2!?!”;
//抛出新异常(“WTF2!?!?”;
//};
ShowDialog();
}
静态void MyCanelEventHandler(对象发送方,CancelEventArgs e)
{
MessageBox.Show(“MyCanelEventHandler”);
抛出新异常(“WTFCEH!?!?”;
}
}
}
调试101是获取一个调用堆栈。
我在10分钟内得到了一个呼叫堆栈
OP做出了三个无效的假设,即使经过长时间的讨论也无法理解
异常正在被吞没
它并没有被吞下,只是通过了他未捕获的异常处理程序
我的代码演示了这一点,但OP没有遵循
解决方案没有无人操作的代码
再次出错OpenFileDialog是非托管代码
正在从托管代码引发异常
又错了
从非托管代码的回调引发异常
回调中的第一行
Degbug 101正在获取一个调用堆栈
UncaughtExceptionHandler.exe!UncaughtExceptionHandler.MainWindow.MyCanelEventHandler(对象发送器,System.ComponentModel.CancelEventArgs e)第55行C#
comdlg32.dll!CFileOpenSave::\u NotifyFileOkChangeCallback()+0x18字节
comctl32.dll_DPA_EnumCallback@12()+0x20字节
comdlg32.dll!CFileOpenSave::\u NotifyFileOk()+0x3d字节
comdlg32.dll!CFileOpenSave::_CleanupDialog()+0x46c2字节
comdlg32.dll!CFileOpenSave::_HandleOkAndClose()+0x3a字节
comdlg32.dll!CFileOpenSave::\u OnCommandMessage()+0xf432字节
comdlg32.dll!CFileOpenSave::s_OpenSaveDlgProc()+0x1f42字节
user32.dll_InternalCallWinProc@20()+0x23字节
user32.dll_UserCallDlgProcCheckWow@32()+0xa9字节
user32.dll_DefDlgProcWorker@20()+0x7f字节
user32.dll_DefDlgProcW@16()+0x22字节
好的,我解决了我的问题
谷歌搜索、冲浪等等,我最终还是和他分手了。现在我清楚了FileOk事件是如何在另一个dispatcher上处理的,因此解决方案很简单:
private void ButtonB_Click(object sender, RoutedEventArgs e)
{
var ofd = new OpenFileDialog();
ofd.FileOk += (s, ce) => {
this.Dispatcher.BeginInvoke((Action)(() =>
{
//We can throw:
throw new Exception("Yay! This exception is now caught by the UnhandledException handler!");
//or, alternatively, our component can do work that possibly throws:
Component.DoFoo();
}));
};
ofd.ShowDialog();
}
这样可以确保将异常传递给正确的dispa