Процесс прекращен из-за StackOverflowException - PullRequest
7 голосов
/ 15 декабря 2010

Это сложная ситуация, чтобы объяснить. Имейте сервисный процесс, который запускает 2 потока, каждый поток зацикливается навсегда, но спит по 5 минут каждый после завершения работы.

Проблема в том, что мой второй поток завершается задолго до того, как полезная нагрузка была даже завершена, без видимой причины, и я также не могу поймать исключение, так как оно, похоже, вызывается извне процесса делегата?

Любые предложения о том, как найти проблему?

Код ....

public void StartService()
{
  ThreadStart stRecieve = new ThreadStart(DownloadNewMail);
  ThreadStart stSend = new ThreadStart(SendNewMail);
  senderThread = new Thread(stRecieve);
  recieverThread = new Thread(stSend);

  sendStarted = true;
  recieveStarted = true;

  senderThread.Start();
  recieverThread.Start();
}

private void DownloadNewMail()
{
  while(recieveStarted)
  {
    //Payload....

    if (recieveStarted)
    {
      Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0));
    }
  }
}

private void SendNewMail()
{
  while(sendStarted)
  {
    //Payload....

    if (sendStarted)
    {
      Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0));
    }
  }

}

Ответы [ 3 ]

8 голосов
/ 15 декабря 2010

Попробуйте проверить длину стека вызовов в вашем коде:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            Hop();
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception - {0}", e);
        }
    }

    static void Hop()
    {
        CheckStackTrace();
        Hip();
    }

    static void Hip()
    {
        CheckStackTrace();
        Hop();
    }

    static void CheckStackTrace()
    {
        StackTrace s = new StackTrace();
        if (s.FrameCount > 50)
            throw new Exception("Big stack!!!!");
    }
}
6 голосов
/ 15 декабря 2010

Если у вас возникли проблемы с отслеживанием последовательности выполнения кода вашего приложения, попробуйте зарегистрировать вход методов с отметкой времени и идентификатором потока.

Кроме того, вы не можете перехватить исключение, потому что это исключение StackOverflowException.

См. Msdn: «Начиная с .NET Framework версии 2.0, объект StackOverflowException не может быть перехвачен блоком try-catch, и соответствующий процесс завершается по умолчанию. Следовательно, пользователям рекомендуется написать свой код для обнаружения и предотвращения». переполнение стека. Например, если ваше приложение зависит от рекурсии, используйте счетчик или условие состояния для завершения рекурсивного цикла. "

4 голосов
/ 15 декабря 2010

Используете ли вы какую-нибудь тяжелую библиотеку для таких задач, как DownloadNewMail и SendNewMail? Например, я столкнулся со StackOverflows при запуске больших заданий с использованием Microsoft.SqlServer.Dts.Runtime.Package. Попробуйте запустить одну и ту же рабочую нагрузку последовательно в приложении командной строки, чтобы проверить, сохраняется ли проблема.

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