c#.net循环线程堆栈溢出

时间:2009-05-05 21:43:56

标签: c# .net winforms multithreading

我正在尝试在后台运行一个任务,检查数据库中是否存在表中的多个记录,如果自上次检查后该数字已更改,请获取这些记录,并对它们进行一些处理。

使用以下代码,我在大约两个小时后收到堆栈溢出。在此期间,应用程序什么都不做,只是检查,并且没有任何作业被添加到数据库中。

private Thread threadTask = null;
private int recordCount = 0;

private void threadTask_Start()
{
    if (threadTask == null) {
        threadTask = new Thread(taskCheck);
        threadTask.Start();
    }
}

private void taskCheck()
{
     int recordCountNew = GetDBRecordCound();
     if (recordCountNew != recordCount)
     {
         taskDo();
         recordCount = recordCountNew; // Reset the local count for the next loop
     }
     else
         Thread.Sleep(1000); // Give the thread a quick break

     taskCheck();          
}

private void taskDo()
{
    // get the top DB record and handle it
    // delete this record from the db
}

当它溢出时,调用堆栈中有大量taskCheck()。 我猜测taskCheck()永远不会完成,直到taskCheck()完成,ergo溢出,因此它们都保留在堆栈中。 这显然不是解决这个问题的正确方法,那是什么?

2 个答案:

答案 0 :(得分:9)

你得到一个堆栈溢出,因为在taskCheck结束时,你再次调用taskCheck。你永远不会退出函数taskCheck,你最终会越来越多地调用,直到你的堆栈溢出。你应该做的是在taskCheck中使用while循环:

private void taskCheck()
{
   while(true)
   {
       int recordCountNew = GetDBRecordCound();
       if (recordCountNew != recordCount)
       {
           taskDo();
           recordCount = recordCountNew; // Reset the local count for the next loop
       }
       else
           Thread.Sleep(1000); // Give the thread a quick break
   }
}

答案 1 :(得分:1)

我假设你有task_Check(),你实际上是指taskCheck()(反之亦然)。也就是说,您正在调用taskCheck()方法recursively。避免在这里讨论架构,你可以删除该调用并让threadTask_Start()在while循环中重复一次。