C# 吞咽异常是否会消除抛出异常的性能影响?

C# 吞咽异常是否会消除抛出异常的性能影响?,c#,asp.net,performance,exception-handling,C#,Asp.net,Performance,Exception Handling,在使用Response.Redirect()时遇到一些未处理的异常后,我仔细阅读了它,似乎有几个人建议改用ApplicationInstance.CompleteRequest(),以避免每次重定向都出现未经处理的ThreadAbortException,从而避免性能下降。但假设你捕捉到了下面的异常 try { response.Redirect("Default.aspx", false); response.End(); } catch (ThreadAbortExcepti

在使用
Response.Redirect()
时遇到一些未处理的异常后,我仔细阅读了它,似乎有几个人建议改用
ApplicationInstance.CompleteRequest()
,以避免每次重定向都出现未经处理的
ThreadAbortException
,从而避免性能下降。但假设你捕捉到了下面的异常

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

当异常现在被吞没时,这会消除对性能的影响吗?

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

在我的计算机上抛出异常大约需要0.042ms,加上处理异常大约需要0.026ms只要未连接调试器。如果我使用Visual Studio 2015调试器运行调试器,它的运行时间最多可达15毫秒,使用调试器进行任何操作的差异都会消失在噪音中

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

如果异常的开销太大以至于很明显,那么首先在不使用调试器的情况下运行它,然后可能需要重新编写代码

在非调试模式下,您可能每秒抛出和处理数千个异常,也就是说,它们并不昂贵,需要大量使用


private const int DataSize=1000;
私有常量字符串TestInt=“1”;
静态void Main(字符串[]参数)
{
#如果调试
编写(“调试代码”);
#否则
控制台。编写(“发布代码”);
#恩迪夫
Write(System.Diagnostics.Debugger.IsAttached?“已连接调试器”。:“无调试器”);
Console.WriteLine($”{DataSize}of\“{TestInt}\”);
var seedData=新列表();
AddRange(可枚举.重复(TestInt,DataSize));
var stopWatch=new System.Diagnostics.stopWatch();
//处理
stopWatch.Restart();
var exceptions=新列表();
foreach(种子数据中的变量项)
{
尝试
{
var x=int.Parse(项目);
}
捕获(例外情况除外)
{
例外情况。添加(ex);
}
}
var已用=秒表已用;
WriteLine($“Handled{appeased}.”);
//吞咽
stopWatch.Restart();
foreach(种子数据中的变量项)
{
尝试
{
var x=int.Parse(项目);
}
捕获(例外情况除外)
{
}
}
已用=秒表。已用;
Console.WriteLine($“吞食{appeased}”);
//但是我会使用TryParse()来完成这个任务
stopWatch.Restart();
var failedStrings=新列表();
foreach(种子数据中的变量项)
{
int x;
如果(!int.TryParse(项目,输出x))
失败字符串。添加(项);
}
已用=秒表。已用;
WriteLine($“Tryparse{appeased}”);
Console.ReadKey();
}
发布代码,没有调试器。1000个“x”

处理时间:00:00:00.0632112

00:00:00.0366465

特里帕斯00:00:00.0000955

调试代码,没有调试器。1000个“x”

处理时间:00:00:00.0743439

00:00:00.0491802

特里帕斯00:00:00.0001026

发布代码,附加调试程序。1000个“x”

处理时间:00:00:15.3732464

00:00:15.2940802

特里帕斯00:00:00.0001101

调试代码,附加调试程序。1000个“x”

处理时间:00:00:15.1689722

00:00:15.1741098

特里帕斯00:00:00.0001026

发布代码,没有调试器。“1”中的1000个

处理时间:00:00:00.0001697

00:00:00.0001575

特里帕斯00:00:00.0001756

调试代码,没有调试器。“1”中的1000个

处理时间:00:00:00.0002214

00:00:00.0001946

特里帕斯00:00:00.0001093

发布代码,附加调试程序。“1”中的1000个

处理时间:00:00:00.0001807

00:00:00.0003288

特里帕斯00:00:00.0003351

调试代码,附加调试程序。“1”中的1000个

处理时间:00:00:00.0001117

00:00:00.0000884

特里帕斯00:00:00.0000911


如果有疑问,尝试分析它。我怀疑捕获异常不会有任何性能改进。此外,您无法真正捕获ThreadAbortException,因为它将在catch块的末尾自动重新启动。
    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();
    }