1

原谅我的术语,我不是很熟悉System.Threading,但如果我有类似下面的内容:

private static int _index;
private static List<int> _movieIds = new List<int>();

static void Main(string[] args)
{
    // the below call populates the _movieIds list variable with around 130,000 ints
    GetListOfMovieIdsFromDatabase(); 

    _index = 0;
    Thread myThread = new Thread(DoWork);
    myThread.Start();
}

public static void DoWork()
{
     // do something with the value of _index (iterate through the _movieIds list) then recursively call DoWork() again

     Thread.Sleep(400);

     _index++;

     DoWork();
}

这是不好的做法吗?我正在迭代int's在类级别定义为成员的私有静态列表,因此第一次迭代DoWork()将使用第一个值_index(为了简单起见,我没有解释),然后是第二次迭代(递归调用)将与第二个值一起使用_index,依此类推。

我问这个的原因是因为在运行这个应用程序大约 12 小时后我得到了一个堆栈溢出异常,我相信这是因为递归调用。

4

3 回答 3

5

是的。您最终总会出现堆栈溢出,因为调用堆栈永远没有机会展开。

不要通过递归调用增加index变量,而是在线程中使用循环。

public static void DoWork()
{
     while(true)
     {    
          // do something with the value of _index (iterate through the _movieIds list) then recursively call DoWork() again

         Thread.Sleep(400);

         _index++;

         // break when a condition is met   
      }
}
于 2013-10-12T23:23:34.600 回答
2

的,因为线程永远不会退出。您需要提供退出条件才能使堆栈展开。

我假设您正在尝试并行调用多个方法,而递归不会这样做。它仍然会串行调用该方法,其好处是可以在下一次使用一次运行的结果。由于DoWork没有结果,这里的递归毫无意义。

我认为您没有理由递归调用此方法。在最坏的情况下,您可以调用DoWork一个递增的简单循环_index。您可以尝试使用Parallel.For并行执行工作以提高性能。

于 2013-10-12T23:25:40.930 回答
1

您应该寻找尾递归的概念。

通过实现尾递归,您每次进行递归调用时都不会消耗另一个堆栈。

这个概念本身解释了为什么 http://blogs.msdn.com/b/chrsmith/archive/2008/08/07/understanding-tail-recursion.aspx

于 2013-11-24T18:09:00.340 回答