【问题标题】:Windows service with SQL Loop throwing unhandled exception带有 SQL 循环的 Windows 服务引发未处理的异常
【发布时间】:2016-02-23 20:51:37
【问题描述】:

我是 C# 新手,使用具有计时器的 Windows 服务,但自动重置设置为 false,因此它应该运行无限循环查询 Sql 数据库。如果 SQL 返回记录,则该过程运行良好,但是当没有找到记录时,服务会在 10 到 12 分钟后引发异常,System.StackOverflowException 未处理,这不清楚(对我来说)。不确定如何更好地捕捉问题或如何纠正。任何帮助将不胜感激。

`private static bool LoadRequests() {

        // check for requests will return combined Header/Detail record
        bool RequestsLoaded = false;
        string XMLURL = "";
        string currentWorkingDirectory = "";
        string text = "";
        int rowcounter = 0;

        try
        {
            //Summary List will be a subset of requested items, by ID# 
            var SummaryInfoList = new List<SummaryInfo>();

            ReqHdrPlusDtlList myReqHdrPlusDetailList = new ReqHdrPlusDtlList();
            List<ReqHdrPlusDtl> myReqHdrPlusDetailList = myReqHdrPlusDetailList.GetReqHdrPlusDtlList();

            if (myReqHdrPlusDetailList != null && myReqHdrPlusDetailList.Count > 0)
            {
                // set check for last record 
                ReqHdrPlusDtl last = myReqHdrPlusDetailList.Last();

                // scroll through each record in  Request List 
                foreach (ReqHdrPlusDtl detailrec in myReqHdrPlusDetailList)
                {
        /// process id records ...
        /// ...

                } // exit for/each 

            }  
            else
            {
                //no records in list sleep for half a second before proceeding 
                Thread.Sleep(500);
                text = "Done sleeping...";
                WriteToAppLog(text);
            }

            //As soon as one request is fully processed, get the next pending record.
            LoadRequests();
        }   // ends try  
        catch (Exception e)
        {
            WriteErrorMessageToAppLog(e);
            RequestsLoaded = false;
        }

        return RequestsLoaded;
    }`

【问题讨论】:

    标签: c# exception service


    【解决方案1】:

    当您查找 the exception in the docs 时,它会说明以下内容。

    执行堆栈溢出时抛出的异常,因为它包含太多的嵌套方法调用。

    当您有无限循环时,通常会发生此异常,例如在您的代码中。 您正在使用递归(递归是一种重要的编程技术,它会导致函数调用自身,source)。 因为你不断地一遍又一遍地调用自己的函数,所以你不断地建立堆栈,直到它溢出。
    您应该重写该函数,使其真正结束。
    我建议使用DispatcherTimer 每 500 毫秒调用一次函数,而不是 Thread.Sleep(),因为 Thread.Sleep() 还会阻止该线程上的任何代码执行。

    private DispatcherTimer _dispatcherTimer;
    
    private void SetUpTimer(){
        _dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
        _dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
        _dispatcherTimer.Interval = TimeSpan.FromMilliseconds(500);
        _dispatcherTimer.Start();
    }
    
    private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
        LoadRequests();
    }
    

    注意:我没有测试代码,也有一段时间没有写过 c#,虽然它应该可以帮助你到达那里

    【讨论】:

    • 谢谢。我将审查调度程序计时器
    • @Fondah 让我们知道我们的答案是否通过投票和接受答案解决了您的问题。
    【解决方案2】:

    您正在使用导致堆栈溢出问题的递归调用。摆脱递归调用更正。可能做一个控制循环如下:

    bool success = true;
    while(success)
    {
        try
        {
            LoadRequests();
            Thread.Sleep(500);
        }
        catch (exception ex)
        {
            //Log Error ex.Message;
            success = false;
        }
    }
    

    一旦你消除了调用自身内部的函数,堆栈溢出问题应该得到解决。

    编辑

    另一个评论是,递归是永无止境的(没有控制语句来阻止执行),这是一个很大的禁忌。如果您必须使用递归,那么必须有一种方法可以退出该方法(停止条件)。话虽如此,几乎每个递归问题都可以迭代解决,这样做非常有益,因为它消耗的系统资源要少得多。上面列出的代码将是一个迭代解决方案。

    【讨论】:

    • 谢谢。这个例子很有帮助,非常感谢。
    猜你喜欢
    • 2013-09-21
    • 1970-01-01
    • 2013-01-29
    • 2010-09-17
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多