0

我有一个小代码示例:

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

GetAllItems 方法进入 DB 并获取集合的所有新项目 -> allItems。然后,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.您对使用定时器代替自调用方法有何看法?

4

4 回答 4

1

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

于 2009-10-26T22:08:56.520 回答
1

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

只需使用一个简单的循环并在其间发送线程休眠一段时间。

于 2009-10-26T22:09:07.440 回答
0

MS IL 有 .tail 操作码。但是c#点想识别尾递归(。顺便说一下,尾递归在.net中太慢了((

于 2009-10-26T22:11:21.910 回答
0

Why do you need to recurse at all? There is no flow control statement that will allow the method to stop recursing and exit the chain. The infinite recursions is probably what is causing the overflow. A better solution would to do away with the recursion altogether. Removing the else wrapper accomplishes the same result without having to recurse:

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

This will accomplish the same result without getting stuck in a loop. Then you can implement rules to repeat the call in the context of the execution environment: a button click on a form or a timer on a service application.

于 2009-10-26T22:55:10.917 回答