简体   繁体   English

Application.ThreadException 的 Win32Exception 类型不正确

[英]Application.ThreadException is getting incorrect Win32Exception type

We have a very large complicated application that has a ThreadException handler intialized at startup, and any exceptions thrown by the application that are not handled immediately are handled by this ThreadException handler in a unified way.我们有一个非常大的复杂应用程序,它在启动时初始化了一个 ThreadException 处理程序,应用程序抛出的任何未立即处理的异常都由这个 ThreadException 处理程序统一处理。

This mostly works...but we have a couple custom exception types that we want to handle with this exception handler, and for some reason these exception types always show up in the ThreadException handler as just System.ComponentModel.Win32Exception types, instead of our custom types.这主要是有效的……但是我们有几个自定义的异常类型想要用这个异常处理程序来处理,出于某种原因,这些异常类型总是作为 System.ComponentModel.Win32Exception 类型出现在 ThreadException 处理程序中,而不是我们的自定义类型。

I've tried anything I can think of to troubleshoot, including making sure our custom exception classes implement all recommended constructors, including a serialiation constructor.我已经尝试了我能想到的任何方法来排除故障,包括确保我们的自定义异常类实现所有推荐的构造函数,包括序列化构造函数。

Additional info...when I create a new exception with just the message from the existing exception, this comes through as a System.Exception.附加信息...当我仅使用来自现有异常的消息创建新异常时,这会作为 System.Exception 出现。 For example:例如:

                MSCSqlException msx = new MSCSqlException(sqlQuery, sqlParams, sqlException);
                throw new Exception(ex.Message);

works fine and is caught in the exception handler as a System.Exception.工作正常,并在异常处理程序中作为 System.Exception 捕获。

However, if I try something like:但是,如果我尝试以下操作:

                MSCSqlException msx = new MSCSqlException(sqlQuery, sqlParams, sqlException);
                throw new Exception(ex.Message, ex);

Then the exception manager catches the above System.ComponentModel.Win32Exception instead of just a System.Exception.然后异常管理器捕获上述 System.ComponentModel.Win32Exception 而不仅仅是 System.Exception。

Just for completeness, what I WANT to do is something like:只是为了完整性,我想做的是:

                throw new MSCSqlException(sqlQuery, sqlParams, sqlException);

and have the Application.ThreadException handler receive a properly typed MSCSqlException.并让 Application.ThreadException 处理程序接收正确类型的 MSCSqlException。

Any ideas how to get around this?任何想法如何解决这个问题? Is there some quirk of Application.ThreadException that I'm missing related to custom error types?是否存在与自定义错误类型相关的 Application.ThreadException 的一些怪癖?

Our custom exception class:我们的自定义异常类:

[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;
    }
}

We finally figured this out...the issue is a bug or feature in how .Net handles exceptions thrown in a background worker Completed event.我们终于弄清楚了……问题是 .Net 如何处理后台工作人员 Completed 事件中引发的异常的错误或功能。 For whatever reason, it appears that in this case, the .Net run time is passing the innermost exception from the stack trace to the ThreadException handler instead of the expected outermost exception.无论出于何种原因,在这种情况下,.Net 运行时似乎将堆栈跟踪中的最内层异常传递给 ThreadException 处理程序,而不是预期的最外层异常。 This innermost exception when a SQLException is thrown is a Win32Exception.当抛出 SQLException 时,这个最内层的异常是 Win32Exception。

More info on this here:更多信息在这里:

Application.ThreadException is getting incorrect Win32Exception type Application.ThreadException 的 Win32Exception 类型不正确

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM