加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 奇怪的行为:捕获ThreadAbortException并抛出不同的异常

发布时间:2020-12-15 22:17:19 所属栏目:百科 来源:网络整理
导读:调查这个问题的结果: Rethrowing exception in Task doesn’t make the Task to go to faulted state,我注意到ThreadAbortException的一些非常奇怪的行为,我无法理解. 现在,我知道ThreadAbortException是一种非常特殊的异常.当它说:documentation时,它非常
调查这个问题的结果: Rethrowing exception in Task doesn’t make the Task to go to faulted state,我注意到ThreadAbortException的一些非常奇怪的行为,我无法理解.

现在,我知道ThreadAbortException是一种非常特殊的异常.当它说:documentation时,它非常清楚:

ThreadAbortException is a special exception that can be caught,but it will automatically be raised again at the end of the catch block.

场景#1:记录的行为.

static void Main(string[] args)
{
    try
    {
        Thread.CurrentThread.Abort();
    }
    catch (Exception tae)
    {
        Console.WriteLine("caught exception: " + tae.GetType().Name);
    }
    Console.WriteLine("will never be reached");
}

正如预期的那样,ThreadAbortException会自动重新抛出,从而产生以下输出:

caught exception: ThreadAbortException

场景#2:当我决定在catch块中抛出一个不同的异常时,它变得有趣:

static void Main(string[] args)
{
    try
    {
        Thread.CurrentThread.Abort();
    }
    catch (Exception tae)
    {
        Console.WriteLine("caught exception: " + tae.GetType().Name);
        throw new ApplicationException(); // will ThreadAbortException take precedence?
    }
    Console.WriteLine("will never be reached");
}

在这种情况下,我假设,尽管抛出了ApplicationException,但无论如何都会重新抛出ThreadAbortException以确保保留记录的行为.令我惊讶的是,这是产生的结果:

caught exception: ThreadAbortException

Unhandled Exception: System.ApplicationException: Error in the application.
   at ConsoleApplication1.Program.Main(String[] args) in C:projectsConsoleApplication1Program.cs:line 193

ApplicationException实际上是否替换并阻止抛出ThreadAbortException?!?

场景#3:最后,为了使事情变得更有趣,我用一个try-catch层包装现有的异常处理:

static void Main(string[] args)
{
    try
    {
        try
        {
            Thread.CurrentThread.Abort();
        }
        catch (Exception tae)
        {
            Console.WriteLine("caught exception: " + tae.GetType().Name);
            throw new ApplicationException();
        }
    }
    catch (Exception outerEx)
    {
        Console.WriteLine("caught outer exception: " + outerEx.GetType().Name);
    }
    Console.WriteLine("will never be reached");
}

现在我不太清楚会发生什么.外部catch块会捕获哪个异常?是ApplicationException吗?如果是这样,这是否意味着我将能够吞下异常并实际设法打印出永远不会达到的字符串?

这是实际输出:

caught exception: ThreadAbortException
caught outer exception: ApplicationException

从上面的输出看,外部catch块实际上捕获了ApplicationException.但是在那个catch块结束时,ThreadAbortException现在突然重新出现,并且被重新抛出了?

问题:有人可以解释和调和情景#2和#3吗?在场景#2中,看起来好像ThreadAbortException被另一个异常取代了?然而,在场景#3中,看起来ThreadAbortException仍然存在?这是怎么回事?这种行为是否记录在某处?

解决方法

该行为是特定于实现的.

Ecma-335 VI Annex E,Portability Considerations开始:

This clause gathers together information about areas where this Standard deliberately leaves leeway to implementations. This leeway is intended to allow compliant implementations to make choices that provide better performance or add value in other ways. But this leeway inherently makes programs non-portable. …

进一步(强调我的):

V I . E . 1 Uncontrollable Behavior

The following aspects of program behavior are implementation dependent. >Many of these items
will be familiar to programmers used to writing code designed for >portability (for example,the
fact that the CLI does not impose a minimum size for heap or stack).

  1. Size of heap and stack aren’t required to have minimum sizes

Behavior relative to asynchronous exceptions (see System.Thread.Abort)

Globalization is not supported,so every implementation specifies its culture information including such user-visible features as sort order for strings.

Threads cannot be assumed to be either pre -emptively or non-pre-emptively scheduled. This decision is implementation specific.

Locating assemblies is an implementation-specific mechanism.

Security policy is an implemenation-specific mechanism.

File names are implementation-specific.

Timer resolution (granularity) is implementation -specific,although the unit is specified.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读