c# – 调试后台服务上的堆栈溢出错误

前端之家收集整理的这篇文章主要介绍了c# – 调试后台服务上的堆栈溢出错误前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
这不是一个真正的问题,而是一个有希望帮助别人的答案.

那些以前写过Windows服务的人知道如何才能找到一个bug,特别是如果它只发生在现场环境中.在我的情况下,我有一个服务顺利运行了几个小时,然后从堆栈溢出错误中掉下来.没有堆栈跟踪.祝你好运,在干草堆中找到针.

该服务确实产生了一个日志文件,并且该代码充满了日志条目,但正如详细所述,它生成了500 MB的日志文件!你几乎不能打开文件,不要介意分析它.但是你怎么解决这个问题呢?您可以尝试使用较少的信息生成日志文件,或者自动删除较旧的日志条目,因为较新的日志条目正在被写入,但是您会丢失错误的重要上下文.

解决方案是一个日志文件,它将跟踪代码中的循环,并自动删除该循环的每次成功迭代的日志条目.这样,您可以保持高度相关的日志文件,同时保持相对较小的日志文件.当您的服务中断时,您的日志文件将告诉您确切的发生地点,以及所有必要的上下文,以解释其发生的原因和原因.

您可以从http://sourceforge.net/projects/smartl/files/?source=navbar下载此日志文件生成器.它是一个独立的类,它的所有方法都是静态的.提供了一个示例类来显示如何正确使用日志记录方法

public void ExampleMethod()
    {           
        SmartLog.EnterMethod("ExampleMethod()"); 
        try
        {
            SmartLog.Write("Some code happening before the loop");

            Guid exampleLoopID = SmartLog.RegisterLoop("exampleLoopID");
            for (int i = 0; i < 10; i++)
            {
                SmartLog.IncrementLoop(exampleLoopID);

                SmartLog.Write("Some code happening inside the loop.");

            }
            SmartLog.CompleteLoop(exampleLoopID);

            SmartLog.Write("Some code happening after the loop.");

            SmartLog.LeaveMethod("ExampleMethod()");
        }
        catch (Exception ex)
        {
            SmartLog.WriteException(ex);
            SmartLog.LeaveMethod("ExampleMethod()");
            throw;
        }
    }

确保您的应用程序在其根文件夹中具有读写权限.

如果您执行代码,并在循环中断开它,则日志文件将如下所示:

. ENTER METHOD: FirstMethod()
some code happening here.
Calling a different method:

. . ENTER METHOD: ExampleMethod()
some code happening before the loop.

LOOP: doWorkLoopID [4135a8ed-05b7-45de-b887-b2ab3c638faa] - CURRENT ITERATION: 20
some code happening inside the loop.

一旦循环完成,其内容将被删除,您的日志文件将如下所示:

. ENTER METHOD: FirstMethod()
some code happening here.
Calling a different method:

. . ENTER METHOD: ExampleMethod()
some code happening before the loop.

LOOP: doWorkLoopID [4135a8ed-05b7-45de-b887-b2ab3c638faa] - TOTAL ITERATIONS: 22

some code happening after the loop.
. . LEAVING METHOD: ExampleMethod()

some code happening here.
some code happening here.
. LEAVING METHOD: FirstMethod()

我希望这可以帮助有人解决那个可能需要几周的问题.它确实为我做了伎俩.

解决方法

这是我的静态记录器解决方案.所有项目都有用于服务:

申请开始于:

MyLog.Reset();

任何静态或非静态方法都以:

System.Diagnostics.StackTrace stackTrace = new System.Diagnostics.StackTrace(); MyLog.Log("",stackTrace.GetFrame(0).GetMethod().DeclaringType.ToString(),stackTrace.GetFrame(0).GetMethod().Name,0);

结果是一个graphviz图源,如下所示:
请注意,当您从log.text中复制文本以生成GraphViz图时,最后一个关闭的大括号应该手动添加.

digraph G{arrowsize=2.0; ratio=fill; node[fontsize=24];graph [fontsize=24] edge [fontsize=24] node [fontsize=24] ranksep = 1.5 nodesep = .25 edge [style="setlinewidth(3)"]; 

subgraph cluster_Riogrande_UI { node [style=filled]; label = "Riogrande_UI"; color=red  
subgraph cluster_UsersForm { node [style=filled]; _ctor_UF; label = "UsersForm"; color=blue }}
subgraph cluster_Riogrande_DL { node [style=filled]; label = "Riogrande_DL"; color=red  
subgraph cluster_DataAccessUsers { node [style=filled]; _ctor_DAU; label = "DataAccessUsers"; color=blue    }}
_ctor_UF -> _ctor_DAU;
}

这是GraphViz年的图:

这是我使用的类:

namespace Riogrande
{
    public class MyLog
    {
        private static int MaximAcceptedLevel = 5;
        private static string lastMethodName = string.Empty;
        private static string filePath = "log.txt";

        public static void Log(string namespaceName,string className,string methodName,int logLevel)
        {
            if (logLevel < MaximAcceptedLevel)
            using (StreamWriter w = File.AppendText(filePath))
            {
                string namespceName = className.Substring(0,className.LastIndexOf('.')).Replace('.','_');

                if (className.Contains('.'))
                {
                    className = className.Substring(className.LastIndexOf('.') + 1);
                }
                if (className.Contains('+'))
                {
                    className = className.Substring(0,className.LastIndexOf('+'));
                }
                className = className.Replace('.','_');
                string cls = "";
                for (int i = className.Length-1; i > -1; i--)
                {
                    if (Char.IsUpper(className[i]))
                    {
                        if (cls.Length < 3)
                        {
                            cls = className[i] + cls;
                        }
                    }
                }
                string currentMethodName = methodName.Replace('.','_') + "_" + cls;
                w.WriteLine("subgraph cluster_" + namespceName + " { node [style=filled]; label = \"" + namespceName + "\"; color=red   ");
                w.WriteLine("subgraph cluster_" + className + " { node [style=filled]; " + currentMethodName + "; label = \"" + className + "\"; color=blue }}");
                if (!string.IsNullOrEmpty(lastMethodName))
                {
                    w.WriteLine(lastMethodName + " -> " + currentMethodName + ";");
                }
                lastMethodName = currentMethodName;
            }
        }

        public static void Reset()
        {
            File.Delete(filePath);
            using (StreamWriter w = File.AppendText(filePath))
            {
                w.WriteLine("digraph G{arrowsize=2.0; ratio=fill; node[fontsize=24];graph [fontsize=24] edge [fontsize=24] node [fontsize=24] ranksep = 1.5 nodesep = .25 edge [style=\"setlinewidth(3)\"]; ");
                w.WriteLine();
            }
        }    
    }
}

解决方案不提供小尺寸的文件,但您可以在同一个类中实现此选项.

猜你在找的C#相关文章