Сбой сервера из-за ASP.NET-Page (C #) - PullRequest
1 голос
/ 19 ноября 2009

Мой локальный тестовый сервер падает, как только я пытаюсь записать в файл журнала. Я использую это для ASP.NET-страницы, codebehind это C #.

Состав:

/
 Functions.cs
 index.aspx
 index.aspx.cs

Я создаю экземпляр Functions при загрузке index.aspx. В Functions я определяю функцию для ведения журнала, которая вызывается из index.aspx.cs и выглядит следующим образом:

if (_WriterOpen == false)
{
    _Writer = new StreamWriter(_WorkingDir + _Logfile, true);
    _WriterOpen = true;
    _Writer.AutoFlush = true;
}
_Writer.WriteLine(DateTime.Now.ToString() + ": " + String.Format(Note, Args));

_Writer определяется глобально для класса и содержит, как вы видите, StreamWriter. Сам класс имеет деструктор для закрытия любых соединений с файлами;

~Functions()
{
    _Writer.Flush();
    _Writer.Close();
    _Writer.Dispose();
}

Итак, когда я открываю свою страницу, логи пишутся, но затем сервер падает. Поэтому я предполагаю, что проблема где-то в дескрипторе, но я не могу понять, почему ...

Ответы [ 5 ]

3 голосов
/ 19 ноября 2009

Вам не нужен деструктор, StreamWriter уже имеет его.

Вы не должны обращаться к другим объектам из деструктора, так как он будет вызываться сборщиком мусора, остальные объекты находятся в неопределимом состоянии. Вы не знаете, когда он будет вызван, и вы не знаете, в каком потоке он будет вызван. НИКОГДА, НИКОГДА, НИКОГДА не пишите деструктор, это почти всегда плохая идея.

Вы можете поместить свой код очистки в событие Unload, см. Жизненный цикл страницы ASP.NET .

1 голос
/ 19 ноября 2009

Я бы рекомендовал оператор using , который автоматически вызывает вызов dispose. Для ваших целей код будет выглядеть примерно так:

StreamWriter _Writer;

using(_Writer)
{
    if (_WriterOpen == false)
    {
       _Writer = new StreamWriter(_WorkingDir + _Logfile, true);
       _WriterOpen = true;
       _Writer.AutoFlush = true;
    }
    _Writer.WriteLine(DateTime.Now.ToString() + ": " + String.Format(Note, Args));
}

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

Также см. Следующие две статьи:
Статья 1
Статья 2

1 голос
/ 19 ноября 2009

Во-первых: вам не нужно коллировать и закрывать. Смотрите ссылку из MSDN: текст ссылки

Эта реализация Close вызывает метод Dispose, передающий истинное значение.

Вы должны позвонить Close, чтобы убедиться, что все данные правильно записаны в основной поток. После звонка Закрыть, любые операции на StreamWriter может вызвать исключения. Если на диск, вызывающий Close поднимет исключение.

1 голос
/ 19 ноября 2009

Скорее всего, это ошибка переполнения стека, вызванная рекурсивным вызовом.

Вы регистрируете ошибку, которая вызывает ошибку, которая регистрирует, вызывает ... и т.д.

Можете ли вы запустить его в режиме отладки из Visual Studio?

0 голосов
/ 19 ноября 2009

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

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

Я бы предпочел сделать класс наследуемым от IDisposable и поместить туда код очистки. Используйте шаблон утилизации: здесь

...