如何自动重新引发异常

3
如果您在try catch块中包装对HttpResponse.End的调用,则ThreadAbortException将自动重新引发。即使您将try catch块包装在try catch块中,我认为情况仍然如此。
我没有实际应用程序需要完成相同的事情,该怎么办?
namespace Program
{
    class ReJoice
    {
        public void End() //This does not automatically re-raise the exception if caught.  
        {
            throw new Exception();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ReJoice x = new ReJoice();
                x.End();
            }
            catch (Exception e) {}
        }
    }
}

http://blogs.msdn.com/clrteam/archive/2009/04/28/threadabortexception.aspx - AaronLS
3个回答

7

你无法将普通异常更改为具有此行为的异常。ThreadAbortException在此方面具有特殊支持,而您无法在C#中自己实现。

ThreadAbortException是一种特殊的异常,可以捕获,但它会在catch块结束时自动再次引发。


确实,但throw是实际(仅略微手动)的解决方案。 - Noldorin
啊,我在其他地方看到过这行代码,但是误解了它的意思,认为特殊支持是我可以模仿的东西。 - Brian

4

使用普通的throw语句就可以轻松搞定了。

throw;

在相关的catch块中,注意这比执行“throw e;”更有优势,因为它在异常点保留了调用堆栈。
当然,这可能不是您想要的自动化方式,但不幸的是这是不可能的。这基本上是您可以得到的最好解决方案,而且我认为还相当简单。ThreadAbortException在CLR中是特殊的,因为它几乎固有于线程管理。
在您的程序中,您会有类似以下的内容:
namespace Program
{
    class ReJoice
    {
        public void End()
        {
            throw new Exception();
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ReJoice x = new ReJoice();
                x.End();
            }
            catch (Exception e) 
            {
                throw;
            }
        }
    }
}

1
我认为他想要做到即使你不这样做,异常也会自动重新抛出,就像 ThreadAbortException - Mark Byers
@Mark:是的,你说得对,尽管我认为这个解决方案是他能得到的最好的。ThreadAbortException的性质是特殊的,因为CLR在管理线程时固有地使用它。你无法直接从C#中重现这种行为。 - Noldorin

1

你是指像这样吗?

namespace Program
{
    class ReJoice
    {
        public void End() //This does not automatically re-raise the exception if caught.  
        {
            throw new Exception();
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                ReJoice x = new ReJoice();
                x.End();
            }
            catch (Exception e) {
               throw e;
            }
        }
    }
}

编辑:它不会重新引发异常,因为“catch”的意思是处理异常。当异常发生时,由x.End()的调用者决定你想要做什么。通过捕获异常并什么也不做,你表明你想忽略异常。在catch块中,你可以显示一个消息框,或记录错误,完全终止应用程序,或通过包装异常来重新抛出带有附加信息的错误:

throw new Exception("New message", e);

3
"throw e" 会将你的异常跟踪限制在这一行。 - Gregoire
@Greg 如果你想的话就直接 throw。他的需求中没有具体说明。不要因为他的需求模糊而对我进行负面评价! - AaronLS
@Greg 我意识到了。根据情况和框架的位置,每种方法都有其优点。从他给出的示例和要求中,我无法知道哪种方法对他最好。他甚至自己说没有实际应用。你这样想,试图应用一种一刀切的方法是狭隘的。 - AaronLS
1
你说得完全正确。我只是在增加一些深度,因为这种情况,在表面上看来,是结构化异常处理最常见的滥用方式。经验不足的开发人员看到这种模式后,没有清晰的理解就机械地重复使用。也许这种对话可以引起人们的注意。 - Sky Sanders
@Greg 对不起,Greg。我不应该称呼你为心胸狭窄的人。当我读到你的帖子时,我以为你说你已经给我投了反对票,我没有注意到“n't”的部分。 - AaronLS
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接