原谅我的术语,我对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个小时后出现了堆栈溢出异常,我相信这是因为递归调用。
答案 0 :(得分: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
}
}
答案 1 :(得分:2)
是的,因为线程永远不会退出。您需要提供退出条件才能使堆栈展开。
我假设您正在尝试并行调用多个方法,而递归不会这样做。它仍然会串行调用该方法,其好处是可以在下一次使用一次运行的结果。由于DoWork
没有结果,因此这里的递归毫无意义。
我认为没有理由以递归方式调用此方法。在最坏的情况下,您可以在一个增加DoWork
的简单循环中调用_index
。您可以尝试使用Parallel.For
并行完成工作以提高性能。
答案 2 :(得分:1)
你应该寻找尾递归的概念。
通过实现尾递归,每次进行递归调用时都不会使用另一个堆栈。
概念本身解释了原因 http://blogs.msdn.com/b/chrsmith/archive/2008/08/07/understanding-tail-recursion.aspx