Форум: "Основная";
Текущий архив: 2003.12.26;
Скачать: [xml.tar.bz2];
ВнизПротокол работы программы. Найти похожие ветки
← →
azazello (2003-12-12 23:02) [0]Протокол работы программы.
Есть желание добавить в мои проект
фукнцию ведения протокола работы программы.
Чтобы отслеживать поведения программы.
Как мне это сделать, чтобы
выглядело по лучше.
Я уже начал создание.
Класс для протокола.
______________________________________________
TProtokol = class(TObject)
private
public
procedure Write(str: string);
end;
______________________________________________
procedure TProtokol.Write(str: string);
var
f: textfile;
begin
AssignFile(f, "test.txt");
Append(f);
WriteLn(f, DateTimeToStr(Now) + " " + str);
CloseFile(f);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Prot:= TProtokol.Create;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
Prot.Free;
end;
______________________________________________
Строка типа
procedure TMain.btnAddClick(Sender: TObject);
begin
Table1.Append;
Prot.Write("Добавления новой записи в таблицу Test.db");
end;
Будет вставлена в процедуре добавления записи.
Что еще можно добавит, что Окончатьно взять под колпак пользователя
и его корявые крючья.
← →
Юрий Зотов (2003-12-12 23:18) [1]Отличная работа, дружище! Больше ничего не нужно. Пользователь уже и так под полным Вашим колпаком.
Мюллер.
P.S.
А что касается корявых крючьев... то совешенно непонятно, зачем потребовалось плодить аж целый класс, когда нужно простое WriteLn в заранее открытый файл. Ну, на крайний случай, обычная процедура.
← →
azazello (2003-12-12 23:25) [2]Под добавлением я имею виду.
Запись названии процедуры внутри которой была
вызвана процедура Prot.Write(str: string);
Тогда запись будет такой.
12.12.03 procedure TForm1.AddClick Добавление нового клиента.
← →
azazello (2003-12-12 23:28) [3]Только как это сделать, я ума не приложу.
← →
Sergey_Masloff (2003-12-13 01:34) [4]Юрий Зотов © (12.12.03 23:18) [1]
>А что касается корявых крючьев... то совешенно непонятно, зачем >потребовалось плодить аж целый класс, когда нужно простое >WriteLn в заранее открытый файл. Ну, на крайний случай, обычная >процедура.
Ну может как раз класс обеспечивает работу с этим файлом. Открывает там, закрывает когда нужно. Ну и та пресловутая обычная процедура - просто метод этого класса. В чем, собственно, кривизна? ;-)
← →
Юрий Зотов (2003-12-13 02:00) [5]> Sergey_Masloff (13.12.03 01:34) [4]
В том, что не следует плодить сущностей без необходимости. К тому же, зазря гробящих память.
> azazello (12.12.03 23:28) [3]
Не нужны для этой задачи вообще никакие классы. Объявляете глобальную файловую переменную. В OnCreate открываете файл, а в OnDestroy его закрываете. Пишете процедуру записи:
procedure WriteLog(MethodName, Message: string);
Вызываете ее так:
WriteLog("TMain.btnAddClick", "Добавление новой записи в таблицу Test.db");
И все.
Конечно, это не совсем удобно - приходится передавать имя вызвавшего метода. В принципе, его имя можно определить и программно в самой процедуре WriteLog, только задачка эта совсем не тривиальная (а при компиляции без отладочной информации - и вовсе нерешаемая).
Существует еще и компромиссный вариант. Вместо прямого вызова WriteLog вызываете Assert, а в обработчике Application.OnException вытаскиваете из полученного текста имя юнита и номер строки - и передаете их во WriteLog.
Только не надо больше юзеров ругать, лады? У кого там кривее крючья - это еще о-о-чень большой вопрос.
← →
Ihor Osov'yak (2003-12-13 02:37) [6]Гм.. Мысль про ассерт довольно интересная, нужно взять на вооружение.
И настолько очевидная, что обидно, что раньше не сообразил..
И вставлю свои 3 копейки.. Вывод в лог без обработки ошибок - лучше тогда без вывода в лог.. Также некоторое разнообразие вноситься для случая, если приложение многопоточное и/или одновременно работает несколько приложений, пишущих в один лог файл.. Критические секции тогда, или именнованные обьекты синхрогизации..
← →
Sergey_Masloff (2003-12-13 03:01) [7]Юрий Зотов © (13.12.03 02:00) [5]
>> Sergey_Masloff (13.12.03 01:34) [4]
>В том, что не следует плодить сущностей без необходимости.
С другой стороны позволяет отделить мух от котлет. В смысле файл лога в момент открытия программы может существовать. Нужно решить - что с ним делать, затирать или дописывать. Еще какая-то инициализация. Допустим вписать шапку вида:
//**************
// MySuperPuperLog start at 10:07 17-DEC-2003
//************
и так далее. И загромождать OnCreate всем этим тоже не всегда хорошо, так ведь? А так вся эта кухня выносится в отдельный объект.
>К тому же, зазря гробящих память.
Наследник TObject? Несколько байт?
P.S. Я не ради просто спора, хотелось бы понять Вашу позицию. Возможно, я где-то глубоко неправ? Просто я использую уже лет 8 назад написаный мной подобный простенький объектик для лога который просто создает файл (или пересоздает или пишет в конец найденого), в деструкторе прикрывает этот файл за собой а кроме этого форматирует передаваемые строки (ну там чтобы в 80 символов строка, отступы там всякие и так далее). Никаких неудобств не испытываю а наоборот при необходимости в новый проект вставить никаких copy-paste а готовый многократно тестированый код.
← →
Ihor Osov'yak (2003-12-13 03:31) [8]2 [7] Sergey_Masloff (13.12.03 03:01)
и снова копейка..
Какое здесь загромождение (случай многопоточного, но работающего в ед. экз. приложения)?:
procedure ToLog(const s: string);
var
f: text;
begin
EnterCriticalSection(CS0);
try
AssignFile(f, sLogFileName);
if FileExists(sLogFileName) then
Append(f)
else begin
Rewrite(f);
WriteTitle(f);
end;
try
Writeln(f, s);
finally
CloseFile(f);
end;
except
end;
LeaveCriticalSection(CS0);
end;
> никаких copy-paste а готовый многократно тестированый код.
гм, а модульность уже запретили?
← →
Sergey_Masloff (2003-12-13 07:19) [9]Ihor Osov"yak © (13.12.03 03:31) [8]
>Какое здесь загромождение (случай многопоточного, но >работающего в ед. экз. приложения)?:
Тут никакого. Но открытие-закрытие на каждый чих ;-) тоже не есть хорошо.
>гм, а модульность уже запретили?
нет. Просто не вижу особых достоинств модуля по сравнению с "моим" объектом. Как, впрочем, и наоборот ;-) Юрий привел как довод лишнее отъедание памяти, но я полагаю что в данном случае оно крайне незначительно.
В любом случае спасибо за участие в обсуждении.
← →
Anatoly Podgoretsky (2003-12-13 09:55) [10]Sergey_Masloff (13.12.03 07:19) [9]
Мое мнение как раз наоборот, во многопользовательской, многопоточной среде, блокировать ресурс на долгое время не хорошо. Файл должен захватываться только на время добавление записи и как можно быстрее освобождаться, не только файл, а любой ресурс.
← →
y-soft (2003-12-13 10:28) [11]IMHO очень удобно использовать системный журнал Windows - журнал защищен от шаловливых ручек, правильно спроектированные записи занимают мало места, удобно выявлять каскадные ошибки при работе взаимодействующих процессов, да и система сама следит, чтобы файл слишком не раздувался, плюс мощный встроенный просмотрщик.
Понятно, что писать туда нужно только действительно важную критическую информацию, да и для комфорта придется повозиться с созданием ресурса MessageTable и регистрацией источника сообщений.
Но IMHO там, где это действительно нужно, говорить о нарушении принципа "бритвы Оккама" неправильно...
← →
Igorek (2003-12-13 11:39) [12]
> Юрий Зотов © (13.12.03 02:00) [5]
> > Sergey_Masloff (13.12.03 01:34) [4]
> В том, что не следует плодить сущностей без необходимости.
Эту формулировку слишком часто приводят не к месту. А вот напр. в "Паттернах" написано, что-бы программист не боялся заводить классы для, на первый взгляд, элементарных сущностей. И я совершенно согласен. Дело в том, что мир намного сложней чем кажется на первый взгляд. И то, что кажется элементарным, на самом деле - сложный обьект. И программа должна прежде всего правильно отражать прикладную область, а оптимизацию оставьте на потом.
Тут ситуация похожая, как в естественных языках. В одном языке для обозначения цветов есть пару слов, в другом - пару десятков. Второй язык явно богаче ибо его термины более узкие и их больше.
Реальный мир увы не обьектно-ориентированный. Это мы его видим таким. И чем больше мы его детализируем по обьектам, тем больше связей, тонкостей можем выявить.
Я даже подозреваю, что сам естественный язык тормозит прогресс из-за того, что новые термины рождаются слишком медленно.
← →
Ihor Osov'yak (2003-12-13 12:09) [13]2 [9] Sergey_Masloff (13.12.03 07:19)
см. [10] Anatoly Podgoretsky © (13.12.03 09:55)
Плюс еще одно обстоятельство. Логи довольно часто используют для отладки, например, в тех случаях, когда обычный интерактивный отладчик не подходит (например, по причине временных задержек, возникающих из-за того, что программер чего-то там смотрит, мысль думает).. И очень интересно получить фрагмент лога для того момента, когда программа умирает.. Если же не закрывать файл при каждом чихе, то последние записи будут потеряны..
2 [11] y-soft © (13.12.03 10:28)
Ну, я имел ввиду ситуацию как-раз наоборот - пишем побольше.. Я этот прием использую в основном при отладке..
2 [12] Igorek © (13.12.03 11:39)
Лучше перебдеть, чем недобдеть?
Имхо, это не всегда так...
← →
Sergey_Masloff (2003-12-13 19:43) [14]Anatoly Podgoretsky © (13.12.03 09:55) [10]
>Sergey_Masloff (13.12.03 07:19) [9]
>Мое мнение как раз наоборот, во многопользовательской, >многопоточной среде, блокировать ресурс на долгое время не >хорошо. Файл должен захватываться только на время добавление >записи и как можно быстрее освобождаться, не только файл, а >любой ресурс.
Это естественно. Но я не говорю о блокировке. Я говорю что объект обеспечивающий записб лога будет один и в том числе обеспечит многопоточный доступ к файлу но файл будет открыт 1 раз (в конструкторе) и закрыт 1 раз (в деструкторе)
Ihor Osov"yak © (13.12.03 12:09) [13]
>И очень интересно получить фрагмент лога для того момента, >когда программа умирает.. Если же не закрывать файл при каждом >чихе
Flush() и все будет в файле. Проверяем:
AssignFile(f,"testlog.txt");
Rewrite(f);
WriteLn(f,"Test");
Flush(f);
Halt;
файл содержит строку "Test" что и предполагалось. Что-то круче чем Halt программу положит?
Вобщем, пока не вижу противоречия между моим подходом и мнением АП. Игорь, Юрий пока не убедили ;-)
← →
Юрий Зотов (2003-12-13 20:47) [15]> Sergey_Masloff (13.12.03 03:01) [7]
> С другой стороны позволяет отделить мух от котлет.
Обыкновенная процедура справляется с этим ничуть не хуже объекта.
> Нужно решить - что с ним делать, затирать или дописывать.
И при чем здесь объект? Он как-то может это решить?
> Еще какая-то инициализация. Допустим вписать шапку вида...
Существует секция initialization. В том же модуле, где и сама процедура. И мухи по-прежнему оказываются отделены от котлет.
> И загромождать OnCreate всем этим тоже не всегда хорошо, так
> ведь? А так вся эта кухня выносится в отдельный объект.
Который создается все в том же OnCreate. Не вижу разницы.
> Наследник TObject? Несколько байт?
Вы забыли о VMT и прочем. Это будет уже несколько десятков, а может и сотен байт. Тоже немного, но вся программа из мелочей и состоит.
> Я не ради просто спора, хотелось бы понять Вашу позицию.
> Возможно, я где-то глубоко неправ?
Здесь не может быть правых или неправых, потому что это вопрос только стиля. Я предпочитаю именно не плодить сущностей без необходимости и не стрелять из пушек по воробьям. И если есть возможность не в ущерб ничему другому сэкономить хотя бы один байт или одну миллисекунду - обязательно это делаю. Просто для того, чтобы поддерживать в себе именно такой стиль. Во многих случаях он экономит уже далеко не байты и не миллисекунды.
> Просто я использую уже лет 8 назад написаный мной подобный
> простенький объектик для лога который просто создает файл
> (или пересоздает или пишет в конец найденого), в деструкторе
> прикрывает этот файл за собой а кроме этого форматирует
> передаваемые строки (ну там чтобы в 80 символов строка,
> отступы там всякие и так далее).
Точно то же самое можно делать точно тем же самым кодом в обыкновенной процедуре. И тоже без всяких неудобств.
==================
А вот Вам довод посерьезнее. Представьте, что Вы пишете программу, которая работает постоянно и поэтому должна отъедать минимум памяти. Ясное дело, VCL Вы в ней использовать не будете - значит, не сможете использовать и Ваш объект. А вот юнит с процедурой - сможете. Вывод - юнит годится во всех случаях, а объект - не во всех.
> Anatoly Podgoretsky © (13.12.03 09:55) [10]
> Файл должен захватываться только на время добавление записи и
> как можно быстрее освобождаться
Ничто не мешает делать то же самое и в обыкновенной процедуре. Объекты здесь ни при чем.
> y-soft © (13.12.03 10:28) [11]
Использовать системный журнал, или нет - все зависит от задачи. Представьте, например, что лог надо периодически пересылать разработчику по почте (я не клавиатурных шпионах говорю, а о нормальном взвимодействии пользователя с разработчиком). С обычным файлом это куда проще, но в других случаях действительно может быть удобнее системный журнал. Впрочем, объекты к этому тоже отношения не имеют.
> Но IMHO там, где это действительно нужно, говорить о
> нарушении принципа "бритвы Оккама" неправильно...
Вот именно - там, где это действительно нужно.
А не заводить класс для сложения двух чисел.
> Igorek © (13.12.03 11:39) [12]
IMHO, насчет сложности мира, как и насчет идеологии проектирования программ лучше поговорить в "потрепаться". В ЭТОМ же форуме решаются более конкретные вопросы. Извините, но конкретики я в Вашем посте не обнаружил. Могу лишь сказать, что гибкое проектирование вовсе не предполагает обязательное использование объектов для каждого чиха (и от этого менее гибким вовсе не становится). А компьтерная программа все же должна делать то, для чего она написана, а не пытаться охватить всю сложность и разнообразие мира. Иначе для того, чтобы запустить всего лишь Блокнот Вам придется покупать компюьтер стоимостью эдак тысяч в 100 баксов. И даже в этом случае в мире все равно найдется множество неохваченных Блокнотом вещей, верите?
> Ihor Osov"yak © (13.12.03 12:09) [13]
В логах я всегда использую Flush. Как раз по этой причине - чтобы точно знать, где именно умерла программа.
← →
Vuk (2003-12-13 22:23) [16]to Ihor Osov"yak © (13.12.03 03:31) [8]:
Во! У меня почти то же самое слово в слово. Только до кучи, для удобства, есть варианты вызова:
function WriteLog( const FileName, Message : string ) : boolean; overload;
function WriteLog( Message : string ) : boolean; overload;
function WriteLog( const FileName : string; const Fmt : string;
const Args: array of const ) : boolean; overload;
function WriteLog( const Fmt : string;
const Args : array of const ) : boolean; overload;
Если параметр FileName отсутствует, то строка пишется в файл, у которого имя совпадает с именем исполняемого модуля, но с расширением .log
← →
panov (2003-12-13 22:27) [17]Я тоже написал в сове время целый класс для ведения лога.
Причем класс был спроектирован так, чтобы с ним можно было работать из нескольких потоков, не занимая при этом лишнего времени у самих потоков на операции ввода-вывода.
Да еще поместил класс в отделюную DLL.
И сделать это одной процедурой нельзя.
← →
y-soft (2003-12-13 22:29) [18]>Юрий Зотов © (13.12.03 20:47) [15]
Представьте, например, что лог надо периодически пересылать разработчику по почте
Во многих случаях, когда программы работают в удаленных от меня географических точках, я формирую очень подробную информацию о критической ошибке в обработчике OnException верхнего уровня и предлогаю пользователю выслать на мой адрес, и в случае согласия формирую письмо с вложением.
Программа, конечно, получается более объемной, но в скорости не теряет, и дополнительных ресурсов при нормальной работе почти не потребляет, т.к. "лишний" код работает только при возникновении исключения. Зато значительно облегчает диагностику трудноуловимых ошибок в программе к обоюдному с заказчиком удовольствию.
Понятно, что реализуется это в виде отдельного универсального модуля, а не класса (можно вообще вынести в отдельную динамически загружаемую Dll)...
Одновременно, кстати, существует возможность включить ведение постоянного лога, но это реализовано в Dll уже с использованием классов, т.к. лог буферизуется и сжимается "на лету" потоковым архиватором, и было бы весьма громоздко реализовать это без использования объектной модели...
А насчет "бритвы Оккама" - это не камень в Ваш огород, а просто в очередной раз о многовариантности - полностью с Вами согласен, что реализацию диктует задача...
← →
Vuk (2003-12-13 22:31) [19]to panov:
Очередь сообщений + сброс на диск отдельным потоком?
← →
panov (2003-12-13 22:34) [20]>Vuk © (13.12.03 22:31) [19]
да.
← →
Vuk (2003-12-13 22:42) [21]При непустой очереди можно потерять некоторые данные при падении приложения...
← →
Sergey_Masloff (2003-12-13 22:55) [22]panov © (13.12.03 22:27) [17]
>Я тоже написал в сове время целый класс для ведения лога.
ну хоть кто-то меня поддержал ;-)
← →
Anatoly Podgoretsky (2003-12-13 23:08) [23]Ну класс ни противоречит, даже если он не доьбавляет функциональности, при желании ее можно безболезнено нарастить.
← →
Sergey_Masloff (2003-12-13 23:13) [24]Юрий Зотов © (13.12.03 20:47) [15]
>> Наследник TObject? Несколько байт?
>Вы забыли о VMT и прочем. Это будет уже несколько десятков, а >может и сотен байт. Тоже немного, но вся программа из мелочей и >состоит.
Да, насчет нескольких байт - вспылил, был неправ.
← →
Ihor Osov'yak (2003-12-13 23:19) [25]2 [14] Sergey_Masloff (13.12.03 19:43)
>
Flush(f);
Halt;
2 ЮЗ
>В логах я всегда использую Flush. Как раз по этой причине - чтобы точно знать, где именно умерла программа.
По накладным расходам Flush и переоткрытие файла почти одно и то же, но иногда держать постоянно открытый файл не всегда удобно - иногда во время дебага нужно вытереть слышком большой лог, тому подобное..
Еще. Когда-то, еще во времена доса делал иследование - Flush не всегда давал гарантию физического сбрасывания на диск - смартдрайвы всякие, нужно было дергать хитрое прерывания для гарантированого сброса. Закрытие файла такую гарантию давало. За древностью времен всех ньюансов не помню, также не исключаю, что сделаны не совсем верные выводы были в то время.. Но привычка переоткрыватть файл осталась. Подкрепленная вышеупомянутой привычкой усекать лог во время дебага.. Так что есть, то есть..
2 [14] Sergey_Masloff (13.12.03 19:43)
> Что-то круче чем Halt программу положит?
Да много что. halt оно как бы мгновенной смерти не подразумевает - смотрите исходные коды модуля system, в частности procedure _Halt0;
2 [16] Vuk © (13.12.03 22:23)
То же самое с вариантами.. И почти один к одному также :-).. Есть еще варианты с внесением времени события в лог - помогает также иногда..
Еще собираюсь написать с глобальным обьектом синхронизации, для случая несколько пприложений в один лог - но все руки не доходят, да и бага такого еще не было, чтобы однозначно припекло...
Да, пользоветель опционно логирование может отключать, включает только в случае возникновения проблем - они у меня (поользователи) также немного удаленные..
← →
Sergey_Masloff (2003-12-14 00:36) [26]Ihor Osov"yak © (13.12.03 23:19) [25]
>По накладным расходам Flush и переоткрытие файла почти одно и >то же,
Мне казалось что это не так. Я, честно говоря, не проверял так что не исключаю вашей правоты ;-)
>но иногда держать постоянно открытый файл не всегда >удобно - >иногда во время дебага нужно вытереть слышком большой >лог, >тому подобное..
Зависит от задач конечно
>Да много что. halt оно как бы мгновенной смерти не >подразумевает
Ну я имел ввиду более-менее рабочую программу, которую уже отдали пользователям. Там таких страшных крахов быть особо часто не должно же...
>Есть еще варианты с внесением времени события в лог - помогает также иногда..
Ага, еще плюсик моему объекту. У меня юзер все эти параметры из интерфейса настраивает в свойствах объекта при необходимости - а вызов идет всегда один и тот же ;-) WriteToLog() а что он сделает это выбор пользователя. Вобщем, пока вижу и плюсы и минусы.
← →
Ihor Osov'yak (2003-12-14 01:08) [27]2 [26] Sergey_Masloff (14.12.03 00:36)
Вам бы на с# мигрировать, или на smalltalk, там одни классы.. А вот меня немного класс, у которого все методы и члены статические, немного напрягает :-)
> особо часто не должно же...
Все относительно.. Отлаживал надавно один BHO, дающий сбой раз в несколько дней... Только мегабайтовые логи и выручили..
>>Есть еще варианты с внесением времени события
> Ага, еще плюсик моему объекту.
Не вижу преимущества. Скажу по секрету, что у меня также параметры лога юзер настраивает из интерфейса.. Ладно, не будем разжыгать религиозных воен на пустом месте..
← →
Petr V. Abramov (2003-12-14 02:56) [28]Если создается ровно один экземпляр, в использовании класс ничем не будет отличаться от юнита с набором процедур, но съест (по-моему) 76 + Lengtn(ClassName) + 4*кол_во_методов байт (это если без DMT и RTTI). Поэтому класс-наследник TObject стОит использовать, если:
Будет создаваться больше одного экземпляра
Планируются наследники с переписанными виртуальными методами
Будет использоваться RTTI
Юнит с набором процедур ( рАвно как и набор процедур без юнита) также является сущностью, хотя и отличной от класса, но связанной с последним глубОкопорытой концептуально-архитектурной взаимозависимостью имплементации, так что, (хочешь жни, а хочешь куй :), динамика роста количества сущностей не поменяется.
← →
Sergey_Masloff (2003-12-14 10:42) [29]Ihor Osov"yak © (14.12.03 01:08) [27]
>2 [26] Sergey_Masloff (14.12.03 00:36)
>Вам бы на с# мигрировать, или на smalltalk, там одни классы..
не пОнял... меня похоже только что послали?! ;-))))))
>что у меня также параметры лога юзер настраивает из >интерфейса..
через глобальные переменные?
>Ладно, не будем разжыгать религиозных воен на пустом месте..
Точно. Как видим, КРИТИЧНЫХ преимуществ для большинства задач нет ни у того ни у другого метода.
Petr V. Abramov © (14.12.03 02:56) [28]
>но связанной с последним глубОкопорытой концептуально->архитектурной взаимозависимостью имплементации
"когда наши корабли бороздят просторы..." ;-) просто вспомнилось.
← →
Ihor Osov'yak (2003-12-15 00:20) [30]2 [29] Sergey_Masloff (14.12.03 10:42)
> меня похоже только что послали?!
неа.. Просто немного поворчал.. Ворчливый я.. Да и при определенных обстоятельствах упоминание шарпа как комплимент можно посчитать.
Да и повода посылать как бы не было.
> через глобальные переменные?
неа. Снова не угадали.. Через функции типа GetXXX, SetXXX, того же модуля, где ToLog живет.. Как в старые, добрые, доопеповские времена.. Ну не люблю я глобальных также, как и "чисто" статических классов..
> КРИТИЧНЫХ преимуществ для большинства задач нет ни у того ни у другого метода
Верно. Я с этим согласен. Но в таких случаях лично я использую правило номер два: "Зачем сложно, если можно просто?".
← →
panov (2003-12-15 01:35) [31]Но в таких случаях лично я использую правило номер два: "Зачем сложно, если можно просто?".
Представим, что решена задача, в которой необходимо было выбрать "более сложное решение", которое можно встроить в любое свое приложение.
Неужели без особых на то причин нужно в других приложениях "изобретать" более простое решение?
← →
Anatoly Podgoretsky (2003-12-15 01:39) [32]Или надо сменить форматы, место вывода логов, класс обеспечит прозрачное изменение, но если просто надо в нескольких местах программы сделать тестовый вывод, тогда можно простой функцией или вообще прямо в коде. Все свое применение. Класс даст гибкость и абстрагирование.
← →
azazello (2003-12-15 04:59) [33]Класс лучшее чем простая процедура, вот еще по какой причине.
Вводим новое свойство
TProtokol.Enable;
procedure TForm1.FormCreate(Sender: TObject);
begin
Prot:= TProtokol.Create;
Prot.Enable:= false; // протокол не будет работать :)
end;
И получается одной строкой отключить ведения протокола.
А с процедурой вам придется вручную удалять строки.
← →
Юрий Зотов (2003-12-15 07:38) [34]> azazello (15.12.03 04:59) [33]
> А с процедурой вам придется вручную удалять строки.
А если подумать?
← →
Ihor Osov'yak (2003-12-15 10:04) [35]2 [31] panov © (15.12.03 01:35)
см [34] Юрий Зотов © (15.12.03 07:38)
:-)
← →
Erik (2003-12-15 11:08) [36]Раз тут идет такая пянка, то я вставлю свое слово. :) Я стороник простых процедур. Потомучто они проще, а лог должен быть надежным! Правило чем проще, тем надежнее еще никто неотменял. Хотя делал это и в классе, но не в отдельном. А закрывать фаил обязательно, иначе проблем можно огрести.... Если хочется сразу записаные данные увидеть, то никакой flush непоможет. А чтобы небыло падения производитальности, надо закрывать в отдельной процедуре. Напримаер чарез 5с безделия. Надеюсь всем понятно как это сделать.
← →
Erik (2003-12-15 11:10) [37]Например так:
Status := WaitForMultipleObjects(Ord(High(tmEvent.Event))+1, @tmEvent.Event , false, 5000);
if FActive and (TActivEvent(Status)<>actExit) then exit;
FActive := True;
Case TActivEvent(Status) of
actExit: Terminate;
actCmd: Log;
else
if Status = WAIT_TIMEOUT then Close;
end;
procedure TRealEvent.Close;
begin
FileActive := False;
{$I-}
Flush(F);
CloseFile(F);
{$I+}
end;
procedure TRealEvent.Log;
Var Buf: String;
Const LogFile = "C:\UDPLog.txt";
begin
Buf := Format("%d;%d;%d;%d;",[DecNoToInt(Params.Decoder),Params.Cmd,
fConf.Code, fConf.Content]);
if not FileActive then begin
AssignFile(F,LogFile);
{$I-}
Reset(F);
{$I+}
IOResult;
if Not FileExists(LogFile) then
Rewrite(F);
FileActive := True;
end;
Append(F);
Writeln(F,Buf);
end;
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.12.26;
Скачать: [xml.tar.bz2];
Память: 0.6 MB
Время: 0.007 c