我有一个针对桌面操作系统(XP,Vista,Win7)的应用程序以及运行Windows XP Embedded的移动设备。所有平台都运行完整的.Net Framework,不 Compact Framework。该应用程序使用AppDomain.UnhandledException
事件来检测并记录任何致命的应用程序错误。没有什么不寻常的,它完美无缺 - 至少在桌面操作系统上。
在应用程序的另一个位置,有一段代码调用NetworkInterface.GetAllNetworkInterfaces
方法来获取计算机上的NIC列表。在Windows XP Embedded上 - 但不是桌面操作系统 - 一旦调用此方法,当发生未处理的异常时,AppDomain.UnhandledException
事件不再触发。相反,应用程序崩溃,甚至没有显示标准的.Net崩溃对话框。
这是一个已知的错误,还是我做错了什么?有人知道解决方法吗?
以下是重现问题的示例应用程序。这个例子是用WinForms编写的,但同样的问题也出现在WPF中。
using System;
using System.Net.NetworkInformation;
using System.Threading;
using System.Windows.Forms;
namespace BugDemo
{
public class BugDemoForm : Form
{
/// <summary>
/// This is the entry point of the application.
/// </summary>
[STAThread]
static void Main()
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Application.Run(new BugDemoForm());
}
/// <summary>
/// Sets up a simple form with two buttons for reproducing the bug.
/// </summary>
public BugDemoForm()
{
Padding = new Padding(15);
Width = 400;
int halfHeight = (ClientRectangle.Height / 2) - Padding.Vertical;
Button exceptionButton = new Button();
exceptionButton.Dock = DockStyle.Top;
exceptionButton.Height = halfHeight;
exceptionButton.Text = "Test the AppDomain.UnhandledException method";
exceptionButton.Click += exceptionButton_Click;
Controls.Add(exceptionButton);
Button networkInterfacesButton = new Button();
networkInterfacesButton.Dock = DockStyle.Bottom;
networkInterfacesButton.Height = halfHeight;
networkInterfacesButton.Text = "Call the NetworkInterface.GetAllNetworkInterfaces method";
networkInterfacesButton.Click += networkInterfacesButton_Click;
Controls.Add(networkInterfacesButton);
}
/// <summary>
/// Throws an exception on a background thread.
/// This will cause the <see cref="AppDomain.UnhandledException"/> event to fire.
/// </summary>
private static void exceptionButton_Click(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(
delegate(object state)
{
throw new ApplicationException();
});
}
/// <summary>
/// Calls the <see cref="NetworkInterface.GetAllNetworkInterfaces"/> method.
/// Once this method is called, the <see cref="AppDomain.UnhandledException"/> event
/// will no longer fire.
/// </summary>
private static void networkInterfacesButton_Click(object sender, EventArgs e)
{
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
MessageBox.Show("There are " + nics.Length + " network interfaces on this machine.\n\n"
+ "Now that the NetworkInterface.GetAllNetworkInterfaces method has been called, "
+ "the AppDomain.UnhandledException event will no longer fire when running on "
+ "Windows XP Embedded.");
}
/// <summary>
/// Fires whenever an unhandled exception occurs on a background thread.
/// However, once the <see cref="NetworkInterface.GetAllNetworkInterfaces"/> method has been
/// called, this event no longer fires.
/// </summary>
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
MessageBox.Show("The AppDomain.UnhandledException event fired successfully.\n"
+ "The app will now crash, as expected.");
}
}
}