吞下异常是否会消除投掷它的性能?

时间:2011-06-08 00:10:11

标签: c# asp.net performance exception-handling

在使用Response.Redirect()后遇到一些未经处理的异常后,我会将其读取,并且似乎有些人建议使用ApplicationInstance.CompleteRequest()来避免未处理的ThreadAbortException每次重定向,从而避免性能损失。但是,让我们说你抓住了这个例外而不是下面......

try
{
    response.Redirect("Default.aspx", false);
    response.End();
}
catch (ThreadAbortException)
{
    // Do nothing
}

当现在吞下异常时,这会取消对性能的影响吗?

2 个答案:

答案 0 :(得分:5)

异常仍然被抛出,因此产生异常并捕获它的所有开销仍然存在。

答案 1 :(得分:0)

在我的计算机上抛出一个大约0.042毫秒的异常成本,加上大约0.026毫秒来做一些事情。 只要没有连接调试器。 如果我使用Visual Studio 2015调试器运行它,这可以拍摄大约15毫秒,与它一起做任何事情的差异都会在噪声

下面是测试代码和结果,但这是一个任意的基准。在解析非常糟糕的数据的长列表时,我不会使用异常,我会使用TryParse()。

如果异常的开销严重到足以引起注意,首先在没有调试器的情况下运行,然后您可能需要重新编写代码。

在非调试模式下,您可能每秒抛出并处理数千个异常,即它们并不昂贵,使用它们很多。

    private const int DataSize = 1000;
    private const string TestInt = "1";

    static void Main(string[] args)
    {
#if DEBUG
        Console.Write("DEBUG code, ");
#else
        Console.Write("RELEASE code, ");
#endif
        Console.Write(System.Diagnostics.Debugger.IsAttached ? "Debugger attached. " : "no debugger. ");
        Console.WriteLine($"{DataSize} of \"{TestInt}\"");

        var seedData = new List<string>();
        seedData.AddRange(Enumerable.Repeat(TestInt, DataSize));
        var stopWatch = new System.Diagnostics.Stopwatch();

        // Handled
        stopWatch.Restart();
        var exceptions = new List<Exception>();
        foreach (var item in seedData)
        {
            try
            {
                var x = int.Parse(item);
            }
            catch (Exception ex)
            {
                exceptions.Add(ex);
            }
        }
        var elapsed = stopWatch.Elapsed;
        Console.WriteLine($"Handled {elapsed}.");

        // Swallowed
        stopWatch.Restart();
        foreach (var item in seedData)
        {
            try
            {
                var x = int.Parse(item);
            }
            catch (Exception ex)
            {

            }
        }
        elapsed = stopWatch.Elapsed;
        Console.WriteLine($"Swallowed {elapsed}.");

        // But I would do this task using TryParse()
        stopWatch.Restart();
        var failedStrings = new List<string>();
        foreach (var item in seedData)
        {
            int x;
            if (!int.TryParse(item, out x))
                failedStrings.Add(item);
        }
        elapsed = stopWatch.Elapsed;
        Console.WriteLine($"Tryparse {elapsed}.");

        Console.ReadKey();
    }

RELEASE代码,没有调试器。 1000&#34; x&#34;

  

处理00:00:00.0632112。

     

吞下00:00:00.0366465。

     

Tryparse 00:00:00.0000955。

DEBUG代码,没有调试器。 1000&#34; x&#34;

  

处理00:00:00.0743439。

     

吞下00:00:00.0491802。

     

Tryparse 00:00:00.0001026。

RELEASE代码,附加调试器。 1000&#34; x&#34;

  

处理00:00:15.3732464。

     

吞下00:00:15.2940802。

     

Tryparse 00:00:00.0001101。

DEBUG代码,附加调试器。 1000&#34; x&#34;

  

处理00:00:15.1689722。

     

吞下00:00:15.1741098。

     

Tryparse 00:00:00.0001026。

RELEASE代码,没有调试器。 1000&#34; 1&#34;

  

处理00:00:00.0001697。

     

吞下00:00:00.0001575。

     

Tryparse 00:00:00.0001756。

DEBUG代码,没有调试器。 1000&#34; 1&#34;

  

处理00:00:00.0002214。

     

吞下00:00:00.0001946。

     

Tryparse 00:00:00.0001093。

RELEASE代码,附加调试器。 1000&#34; 1&#34;

  

处理00:00:00.0001807。

     

吞下00:00:00.0003288。

     

Tryparse 00:00:00.0003351。

DEBUG代码,附加调试器。 1000&#34; 1&#34;

  

处理00:00:00.0001117。

     

吞下00:00:00.0000884。

     

Tryparse 00:00:00.0000911。