我有一个小代码示例:

private void MonitorItems()
        {
            if (someCondition)
            {
                dateSelected = DateTime.Now;
                GetAllItems();
            }
            else
            {
                if(allItems.Count>0)
                    CheckAllItems();
            }
            MonitorItems();
        }

方法GetAllItems转到数据库并获取集合的所有新项目 - >所有项目。 然后,CheckAllItems方法:

private void CheckAllItems()
        {
            foreach (Item a in new List<Item>(allItems))
            {
                switch (a.Status)
                {
                    case 1:
                        HandleStatus1();
                        break;
                    case 2:
                        HandleStatus2(a);
                        break;
                    case 0:
                        HandleStatus0(a);
                        break;
                    default:
                        break;
                }
            }  
        }

在某些情况下(在HandleStatus1和HandleStatus2中)我需要转到数据库,进行一些更新,然后再次调用方法GetAllItems来填充集合allItems。

这种类型的代码在WinFormsApp中抛出了Stack.Overflow异常。 我有两个问题:
1.这种类型的异常是否会在WinService应用程序中抛出,使用相同的代码?
2.您对使用计时器而不是自我调用方法有何看法?

有帮助吗?

解决方案

“自我调用方法”。更正确地称为“递归方法”。你的解决方案很有创意,我会给你的。但是不要这样做。堆栈空间非常有限。当您转移到服务时,您将看到此问题,并且有更好的方法来处理它。在服务中使用时,计时器非常合适。

其他提示

在您的情况下递归调用该方法与使用计时器一样错误。你不应该做!!

只需使用一个简单的循环,并将线程休眠一段时间。

MS IL有.tail操作码。但是c#dot想要识别尾递归(。顺便说一下,.net中的尾递归是如此之慢((

为什么你需要递归呢?没有流控制语句允许该方法停止递归并退出链。无限递归可能是导致溢出的原因。更好的解决方案是完全取消递归。删除else包装器可以完成相同的结果而无需递归:

private void MonitorItems()
{
    if(someCondition)
    {
        dateSelected = DateTime.Now;
        GetAllItems();
    }
    if(allItems.Count>0)
        CheckAllItems();
}

这将完成相同的结果而不会陷入循环。然后,您可以在执行环境的上下文中实现重复调用的规则:单击服务应用程序上的表单或计时器。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top