我有一个小代码示例:
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.您对使用计时器而不是自我调用方法有何看法?
答案 0 :(得分:1)
“自我调用方法”更准确地称为"recursive method"。你的解决方案很有创意,我会给你的。但是不要这样做。堆栈空间非常有限。当您转移到服务时,您将看到此问题,并且有更好的方法来处理它。在服务中使用时,计时器非常合适。
答案 1 :(得分:1)
在您的情况下递归调用该方法与使用计时器一样错误。你不应该做!!
只需使用一个简单的循环,并将线程休眠一段时间。
答案 2 :(得分:0)
MS IL有.tail操作码。但是c#dot想要识别尾递归(。顺便说一下,.net中的尾递归是如此之慢((
答案 3 :(得分:0)
为什么你需要递归呢?没有流控制语句允许该方法停止递归并退出链。无限递归可能是导致溢出的原因。更好的解决方案是完全取消递归。删除else包装器可以完成相同的结果而无需递归:
private void MonitorItems()
{
if(someCondition)
{
dateSelected = DateTime.Now;
GetAllItems();
}
if(allItems.Count>0)
CheckAllItems();
}
这将完成相同的结果而不会陷入循环。然后,您可以在执行环境的上下文中实现重复调用的规则:单击服务应用程序上的表单或计时器。