我们有一个非常大的复杂应用程序,它在启动时初始化了一个ThreadException处理程序,并且应用程序抛出的任何未立即处理的异常都由此ThreadException处理程序以统一的方式处理。
这大部分都有用......但是我们有一些我们想用这个异常处理程序处理的自定义异常类型,并且由于某些原因,这些异常类型总是在ThreadException处理程序中显示为System.ComponentModel.Win32Exception类型,而不是我们的自定义类型。
我已经尝试过任何我能想到的排除故障的方法,包括确保我们的自定义异常类实现所有推荐的构造函数,包括序列构造函数。
附加信息...当我仅使用来自现有异常的消息创建新异常时,这将作为System.Exception发生。例如:
MSCSqlException msx = new MSCSqlException(sqlQuery, sqlParams, sqlException);
throw new Exception(ex.Message);
工作正常,并作为System.Exception在异常处理程序中捕获。
但是,如果我尝试这样的话:
MSCSqlException msx = new MSCSqlException(sqlQuery, sqlParams, sqlException);
throw new Exception(ex.Message, ex);
然后异常管理器捕获上面的System.ComponentModel.Win32Exception,而不仅仅是System.Exception。
为了完整起见,我想要做的是:
throw new MSCSqlException(sqlQuery, sqlParams, sqlException);
并让Application.ThreadException处理程序接收正确类型的MSCSqlException。
任何想法如何解决这个问题?我是否遗漏了与自定义错误类型相关的Application.ThreadException错误?
我们的自定义异常类:
[Serializable]
public class MSCSqlException : Exception
{
public string SqlCommand { get; private set; }
public object[] SqlParameters { get; private set; }
public MSCSqlException()
{
}
public MSCSqlException(string message)
: base(message)
{
}
public MSCSqlException(string message, Exception inner) : base(message, inner)
{
}
public MSCSqlException(string command, object[] parameters, SqlException sx) : base(CreateUsefulMessage(sx, command, parameters), sx)
{
SqlCommand = command;
SqlParameters = parameters;
}
protected MSCSqlException(SerializationInfo info, StreamingContext context) : base(info, context)
{
SqlCommand = info.GetString("SqlCommand");
}
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException("info");
}
info.AddValue("SqlCommand", SqlCommand);
base.GetObjectData(info, context);
}
public static string CreateUsefulMessage(SqlException sx, string sqlCommand, object[] sqlParameters)
{
string message = sx.Message + Environment.NewLine;
if(sqlParameters != null && sqlParameters.Count() > 0)
{
message = message + "Parameters:" + Environment.NewLine;
foreach(object sp in sqlParameters)
{
message = message + "\t" + sp.ToString() + Environment.NewLine;
}
}
message = message + "SQL Statement:" + Environment.NewLine;
message = message + sqlCommand;
return message;
}
}
答案 0 :(得分:0)
我们终于弄清楚了......问题是.Net如何处理后台工作者已完成事件中引发的异常的错误或特征。无论出于何种原因,在这种情况下,.Net运行时似乎将最内层的异常从堆栈跟踪传递给ThreadException处理程序而不是预期的最外层异常。抛出SQLException时,这个最内部的异常是Win32Exception。
有关这方面的更多信息:
Application.ThreadException is getting incorrect Win32Exception type