C# 递归调用线程方法(System.Threading)是一种不好的做法吗?

C# 递归调用线程方法(System.Threading)是一种不好的做法吗?,c#,multithreading,recursion,C#,Multithreading,Recursion,请原谅我的术语,我不太熟悉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,0

请原谅我的术语,我不太熟悉
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\u索引;
私有静态列表_movieIds=new List();
静态void Main(字符串[]参数)
{
//下面的调用用大约130000整数填充_movieidslist变量
GetListOfMovieIdsFromDatabase();
_指数=0;
螺纹myThread=新螺纹(销);
myThread.Start();
}
公共静态无效工作()
{
//对_index的值执行一些操作(遍历_movieIds列表),然后再次递归调用DoWork()
睡眠(400);
_索引++;
销钉();
}
这是坏习惯吗?我正在遍历在类级别定义为成员的
int的私有静态列表,因此
DoWork()
的第一次迭代将使用
\u index
的第一个值(为了简单起见,我没有解释),然后是第二次迭代(递归调用)将与第二个值
\u index
一起使用,依此类推


我之所以问这个问题,是因为我在运行这个应用程序大约12小时后遇到堆栈溢出异常,我相信这是因为递归调用。是的。最终总会出现堆栈溢出,因为调用堆栈永远没有机会展开

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

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   
      }
}

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

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

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   
      }
}
是的,因为线程永远不会退出。您需要提供一个退出条件,以便堆栈展开

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

我看你没有理由递归调用这个方法。在最坏的情况下,您可以在一个简单的循环中调用
DoWork
,该循环增加
\u索引
。您可以尝试使用
Parallel.For
并行执行工作以提高性能。

是的,因为线程从不退出。您需要提供一个退出条件,以便堆栈展开

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


我看你没有理由递归调用这个方法。在最坏的情况下,您可以在一个简单的循环中调用
DoWork
,该循环增加
\u索引
。您可以尝试使用
Parallel.For
并行工作以提高性能。

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

通过实现尾部递归,您不会在每次进行递归调用时使用另一个堆栈

这个概念本身就解释了原因
您应该寻找尾部递归的概念

通过实现尾部递归,您不会在每次进行递归调用时使用另一个堆栈

这个概念本身就解释了原因

你看过这个问题吗?如果没有停止条件,程序将始终崩溃,因为它是递归的。
DoWork
方法真的没有收到任何参数吗?如果是的话,我认为你不应该使用递归。你看过这个问题吗?如果没有停止条件,程序将始终崩溃,因为它是递归的。
DoWork
方法真的没有收到任何参数吗?如果是这样的话,我认为你不应该使用递归。
while(1)
是非法的。@KirkWoll:我的原始评论说
while(true)
,但黑青蛙在他的编辑中更改了它。
while(1)
是非法的。@KirkWoll:我的原始评论说
while(true)
但黑青蛙在他的编辑中更改了它。