Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# System.Diagnostics.Trace是否有任何性能下降?_C#_Asp.net Mvc 5_Trace_System.diagnostics - Fatal编程技术网

C# System.Diagnostics.Trace是否有任何性能下降?

C# System.Diagnostics.Trace是否有任何性能下降?,c#,asp.net-mvc-5,trace,system.diagnostics,C#,Asp.net Mvc 5,Trace,System.diagnostics,我正在寻找一个简单的本机.NET错误日志解决方案。我对使用log4net、Elmah或任何其他日志库都不感兴趣。下面是我计划使用的内容。我的问题是,我的网站的性能是至关重要的,这个流程是否会带来任何性能问题 Global.asax protected void Application_Start(object sender, EventArgs e) { GlobalFilters.Filters.Add(new HandleExceptionsAttri

我正在寻找一个简单的本机.NET错误日志解决方案。我对使用log4net、Elmah或任何其他日志库都不感兴趣。下面是我计划使用的内容。我的问题是,我的网站的性能是至关重要的,这个流程是否会带来任何性能问题

Global.asax

protected void Application_Start(object sender, EventArgs e)
        {
            GlobalFilters.Filters.Add(new HandleExceptionsAttribute());
        }
句柄异常属性:

public sealed class HandleExceptionsAttribute : HandleErrorAttribute
    {
        private void TraceError(Exception _this)
        {
            Trace.TraceError("{0} Exception {1}", DateTime.Now.ToString("M/d/yyyy h:mmtt"), _this);
        }

        public override void OnException(ExceptionContext filterContext)
        {
            var ex = filterContext.Exception;
            TraceError(ex);
            Task.Run(() =>
            {
                using (var msg = new MailMessage(ConfigurationManager.AppSettings["SendErrorsFrom"], ConfigurationManager.AppSettings["SendErrorsTo"]))
                {
                    msg.Subject = ex.Message;
                    msg.Body = ex.StackTrace;
                    using (var smtp = new SmtpClient())
                        smtp.Send(msg);
                }
            });
        }
    }
web.config:

  <system.diagnostics>
    <trace autoflush="true" indentsize="4">
      <listeners>
        <add name="textWriterListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="logs\log.txt"/>
        <add name="eventLogListener" type="System.Diagnostics.EventLogTraceListener" initializeData="Base Test" />
        <remove name="Default"/>
      </listeners>
    </trace>
  </system.diagnostics>

视情况而定

使用条件编译器属性,这意味着如果在编译时关闭跟踪标志(如在发布模式下),则对TraceError的所有调用都将从编译代码中删除。从表面上看,这将消除大多数实时代码的性能问题,因为性能如此重要,您肯定要在发布模式下编译

但是,在调用
TraceError
中实际找不到的任何补充代码仍将运行。因此,在您的情况下,对
HandleExceptionsAttribute.TraceError()
的调用仍将被执行——它将立即返回,而不执行任何操作

// This code sticks around, and could still have performance implications.
var additionalInfo = GoGetMoreInformation(); 
// This code disappears when compiled
Trace.TraceError("Something went wrong: {0}", additionalInfo); 
当然,另一个不利的方面是,在实时环境中,您无法从跟踪中获得任何信息,因为它们可能非常有用。在您的情况下,这意味着在您的实时系统中抛出的任何异常对您来说都是完全不可见的。如果用户不抱怨结果,就没有任何迹象表明有什么问题

校正
显然,关于
调试
,我上面所说的是正确的,但是默认情况下,VisualStudio将在发布模式构建期间保持跟踪标志处于活动状态。

为每个异常获取电子邮件?祝你好运

目前的代码无法正常工作。这与Trace.TraceError本身无关,而是您想做什么。我有时看到错误循环在几分钟内产生数百万个异常。您正在进行自我造成的拒绝服务攻击。让我们做一些数学。每分钟100万个异常,文本块约为1500字节。网络上的邮件数据量为1,5GB/分钟。这将消耗约25 MBit的网络带宽。这是一个保守的估计。但如果发生这种情况,您的内存将很快耗尽。异步任务方法将对任务进行排队。由于您发送电子邮件的速度比生成异常的速度慢,您很快就会得到一个OutOfMemoryException,您也会尝试通过邮件发送该异常。。。。至少在拒绝服务的情况持续下去之前,您可以很快免费重新启动

更好的方法是编写一个定制的MailTraceListener,它将聚合异常并限制每封邮件发送异常的速率,例如最多1/分钟。然后,您可以添加一个RollingFileTraceListener(不是.NET的一部分。存在外部日志库是有原因的),它将日志记录到一个平面文件中,您可以通过邮件发送聚合摘要。 通过异常消息检测重复异常也很有意义,只记录摘要。例如,始终记录第一个异常,然后再次检查最后一个异常是否与新异常相同。如果是,则增加一个计数器,并继续这样做,直到出现另一个计数器。然后你可以写一个很好的总结,100亿个异常刚刚发生,除了第一个,你没有记录任何异常

例外本身是缓慢的。无论你是否追踪他们,都不起作用。您可以优化跟踪调用,但这是您最不关心的问题。堆栈展开是异常处理中最昂贵的部分。跟踪的主要性能影响来自配置的输出设备。如果你对它进行分析,你会很快发现这一点


正如我在上面所概述的,一个好的错误处理策略并不容易实现,因为您要处理的是几乎任何事情都可能发生的异常情况。包括异常处理成为问题的一部分。您需要彻底地测试它,否则如果没有错误发生,您会发现它工作得很好,但由于某些奇怪的原因,它会在某个角落案例异常发生时崩溃

对于web应用程序,没有理由自行启动——该框架能够通过使用ASP.NET运行状况监视单独进行配置来通知您任何未经处理的异常。看到一个好的开始


还要记住,你的代码将会很难看。当电子邮件服务器配置错误并在异常处理程序中引发异常时会发生什么情况。当事情崩溃而不影响性能时,记录错误是一个非常重要的问题,最好使用经过良好测试的库,而不是尝试在这里推出自己的解决方案。

感谢您的简洁回答,这似乎是合乎逻辑的。在没有第三方库的情况下,还有其他方法可以做到这一点吗?我想做的是通过电子邮件发送错误信息,并将其记录到某个文件中,而不会影响性能。@Cyberdrew:有很多方法。大多数涉及编写自己的日志库。第三方图书馆已经解决了很多棘手的问题。如果您的应用程序不仅仅是一个小型的业余网站,我建议您使用第三方库。它们可以轻松配置为向日志文件、数据库和/或电子邮件发送信息,并为每个目标设置自定义格式和阈值。他们可以异步执行,也可以通过错误处理来执行,这样您就不会在后台线程中删除带有未处理异常的服务器。您应该使用正确的错误处理模块,请尝试Elmah。它通过数据库、文件、电子邮件日志等简单地集成到MVC中。仅供参考,默认情况下VS在发布模式下保持跟踪常量打开,而不是关闭。