В настоящее время у меня есть консольное приложение, написанное на C# для рабочей серверной среды. Это довольно просто, но я тестировал его на + - 3 месяца на моем собственном сервере (полупроизводство, но не катастрофа, если программа не работает). Тем не менее, я получаю ошибки переполнения стека каждые несколько недель.Ошибка переполнения стека в консольном приложении
Конечно, приклеивание всего моего исходного кода здесь будет довольно длинным, поэтому я попытаюсь объяснить это как можно лучше: программа находится в бесконечном цикле (это, вероятно, причина проблемы) , и он проверяет каждую секунду несколько мелких вещей и печатает на консоль так часто (если нет активности, каждые 15 минут, в противном случае - каждую секунду).
Теперь почему и как я могу исправить ошибки переполнения стека? Возможность запускать его на пару недель без проблем может показаться много, но это явно не в среде производства сервера. Я предполагаю, что это факт, что я использую цикл while, но какие у меня альтернативы?
Edit: Вот часть кода:
int timeLoop = 0;
while (true)
{
// If it has been +-10min since last read of messages file, read again
if (timeLoop > 599)
{
Console.WriteLine(DateTime.Now.ToString("HH:mm:ss") + " Reading messages...");
messagesFile = File.ReadAllText(@"messages.cfg");
messages = messagesFile.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
timeLoop = 0;
}
// For each message, check if time specified equals current time, if so say message globally.
foreach (string x in messages)
{
string[] messageThis = x.Split('~');
int typeLoop = 0;
if (messageThis[2] != "no-loop")
typeLoop = Convert.ToInt16(messageThis[2].Remove(0, 5));
DateTime checkDateTime = DateTime.ParseExact(messageThis[0], "HH:mm:ss", null);
if (typeLoop == 0)
{
if (checkDateTime.ToString("HH:mm:ss") == DateTime.Now.ToString("HH:mm:ss"))
publicMethods.sayGlobal(messageThis[1]);
}
else
{
DateTime originalDateTime = checkDateTime;
do
{
checkDateTime = checkDateTime.AddHours(typeLoop);
if (checkDateTime.ToString("HH:mm:ss") == DateTime.Now.ToString("HH:mm:ss"))
publicMethods.sayGlobal(messageThis[1]);
} while (checkDateTime.ToString("HH:mm:ss") != originalDateTime.ToString("HH:mm:ss"));
}
}
timeLoop++;
Thread.Sleep(1000);
}
Кроме того, я забыл, что я на самом деле этот код на Github, который, вероятно, помогает много. Я знаю, что вы не должны использовать какие-либо ссылки для кода и иметь их здесь, поэтому я включил фрагмент выше, но если вы заинтересованы в том, чтобы помочь мне, то в репозитории находится here. Еще одно замечание - я знаю, что делать это так не очень точно по времени, но на данный момент это не очень проблема.
У вас есть трассировка стека? Что-нибудь называет себя рекурсивно? –
это исключение не будет исправлено для вас, если нет никакого кода –
Я могу подтвердить, что циклы 'while' сами по себе ** не ** вызывают переполнение стека. –