2013-10-12 2 views
1

Простите мою терминологию, я не все, что знакомы с System.Threading, но если у меня есть что-то вроде ниже:Неправильная практика рекурсивного вызова метода потока (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

Вы смотрели на этот вопрос? http://stackoverflow.com/questions/145312/maximum-number-of-threads-in-a-net-app – Kousha

+1

Если у вас нет условия остановки, программа всегда будет сбой, потому что она рекурсивна. Действительно ли метод DoWork не получает никаких параметров? Если это так, я думаю, вы не должны использовать рекурсию. –

ответ

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

Это работает, спасибо. –

+0

'while (1)' является незаконным. –

+0

@KirkWoll: Мой оригинальный комментарий действительно сказал 'while (true)', но Black Frog изменил его в своем правлении. – AndyG

2

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

Я предполагаю, что вы пытаетесь вызвать несколько методов параллельно, который рекурсия не делает. Он будет по-прежнему вызывать метод поочередно, с тем преимуществом, что результаты одного прогона могут быть использованы в следующем. Поскольку DoWork не имеет результатов, рекурсия здесь бессмысленна.

Я не вижу причины для вызова этого метода рекурсивно. В худшем случае вы можете позвонить DoWork в простой цикл, который увеличивает _index. Вы могли бы попробовать с помощью Parallel.For, чтобы сделать работу параллельно, чтобы улучшить производительность.

Смежные вопросы