Переполнение стека потока цикла c # .net - PullRequest
1 голос
/ 06 мая 2009

Я пытаюсь запустить задачу в фоновом режиме, проверяя в базе данных количество записей в таблице, и, если число изменилось с момента последней проверки, получить эти записи и поработать с ними.

Используя следующий код, я получаю переполнение стека примерно через два часа. В течение этого времени приложение ничего не делает, просто проверяет, и никакие задания не добавляются в базу данных.

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 (), не переполнится, и, следовательно, почему они все остаются в стеке. Это явно не правильный путь, так что же?

Ответы [ 2 ]

9 голосов
/ 06 мая 2009

Вы получаете переполнение стека, потому что в конце taskCheck вы снова вызываете taskCheck. Вы никогда не выходите из функции taskCheck, вы просто вызываете все больше и больше, пока ваш стек не переполнится. Что вы должны сделать, это сделать цикл while в taskCheck вместо этого:

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 голос
/ 06 мая 2009

Я предполагаю, что у вас есть task_Check (), вы на самом деле имеете в виду taskCheck () (или наоборот). То есть вы вызываете метод taskCheck () рекурсивно . Избегая обсуждения архитектуры здесь, вы можете удалить этот вызов и заставить threadTask_Start () повторить процесс один раз в цикле while.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...