Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];

Вниз

Реализация лог-файла.   Найти похожие ветки 

 
Владислав ©   (2005-12-08 13:59) [0]

Приветствую, Мастера.

Необходимо реализовать запись строковых данных в лог файл. Лог файл должен иметь ограниченный размер. Новые строки добавляются в конец файла. При превышении размера лог-файла установленного ограничения, из начала файла должны удаляться старые строки.
Кроме этого, хотелось бы, чтобы буфер файла периодически сбрасывался на диск, чтобы можно было просматривать лог во время работы приложения.
Что-то особенное, для обеспечения целостности данных не нужно, но и половину строки (обрезанную строку) тоже не хотелось бы оставлять.
Какие есть варианты решения этой задачи?

На уме пока только "самое очевидное" :) Сдвигание информации, содержащейся в файле в начало, при превышении размера, и дописывание новой информации в конец файла. Но что-то мне подсказывает, что это не есть хорошо :)


 
Владислав ©   (2005-12-08 14:00) [1]

Забыл указать.
Если это важно, то Win9x, Win2k, WinXP, D7.


 
Digitman ©   (2005-12-08 14:05) [2]


> Лог файл должен иметь ограниченный размер


уточни - какой ...

это важно для простоты решения


 
dracula ©   (2005-12-08 14:05) [3]

1. Делаеш StringList, и просто начинаешь удалять первые строки из него, при этом добавляя последнии и переодически сохраняешь его в файл.
2. Создаёшь файл открытый на запись и чтение, его можно будет просматривать и в тоже время изменять, делаешь то же самое что и со списком строк, удаляешь первую строку добавляешь в конец новую, но первый вариант мне кажется проще будет.
Можно ещё кучу всего придумать... ну может  кто ещё чего добавит.


 
Fay ©   (2005-12-08 14:06) [4]

2 Владислав ©   (08.12.05 13:59)
> Сдвигание информации, содержащейся в файле в начало,
> при превышении размера, и дописывание новой информации
> в конец файла

Это именно то, что и
> Новые строки добавляются в конец файла. При превышении
> размера лог-файла установленного ограничения, из
> начала файла должны удаляться старые строки.


 
dracula ©   (2005-12-08 14:09) [5]

Да это точно =)


 
Владислав ©   (2005-12-08 14:14) [6]


> Digitman ©   (08.12.05 14:05) [2]
>
> уточни - какой ...
>
> это важно для простоты решения


Этот параметр задается пользователем. По умолчанию лог файл вообще отключен, а размер файла установлен 50 кБ. Сколько же может установить пользователь, я заранее знать не могу. У этой опции ограничение (2^31 - 1)кБ.


 
Владислав ©   (2005-12-08 14:15) [7]


> Fay ©   (08.12.05 14:06) [4]


Я утверждал обратное? :)


 
Anatoly Podgoretsky ©   (2005-12-08 14:21) [8]

Владислав ©   (08.12.05 14:14) [6]
При таких размерах надо очень потрудиться, что бы это было оптимально и не нанесло вреда, ни писателю, ни читателю и без ощутимых задержек. При таких размерах тяжеловать будет и с локальной базой.


 
Владислав ©   (2005-12-08 14:30) [9]


> Anatoly Podgoretsky ©   (08.12.05 14:21) [8]


Вот я и задумался...
Сейчас при превышении размера файл просто обрезается до нулевого размера и запись начинается с начала. По моему мнению, пользы в таком логе очень мало, ведь у большинства пользователей ограничение будет установлено небольшим, и лог будет постоянно перетираться.


 
Anatoly Podgoretsky ©   (2005-12-08 14:42) [10]

Владислав ©   (08.12.05 14:30) [9]
Ну зачем тебе такие большие логи?
Сделай логи по периоду, например один день. Тогда весь лог можно будет загнать и в StringList, да и обрезать ничего не надо будет.
Режим работы простой
1. открыть файл (TFileStream) в режиме записи и разрешение только на чтение для других программ.
2. записать строку
3. закрыть файл.

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

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

Даже синхронизировать не нужно.


 
Digitman ©   (2005-12-08 14:42) [11]


> Владислав ©   (08.12.05 14:14) [6]


TFileStream  - инструмент очевидного решения


 
Владислав ©   (2005-12-08 15:04) [12]

Мне вот придумался такой алгоритм.

Когда размер лога достиг ограничения, сдвигаем данные файла в начало таким образом.
Расчитываем размер блока удаляемых данных в начале файла исходя из размера ограничения. Чем больше ограничение лога, тем больше размер блока.
Сдвигаем данные. Уменьшаем размер файла.
Ищем в начале файла первое вхождение окончания строки. Все, что перед, заменяем пробелами.
В итоге получается файл, у которого, возможно, первая строчка будет выглядеть как пустой. Т.е. "читабельность" сохраниться. Операции "сжатия" лог файла в случае с большими файлами будут редкими, в случае с небольшими файлами хоть и более частыми, но по времени это будет не накладно.

Критика приветствуется ;)


 
Игорь Шевченко ©   (2005-12-08 15:06) [13]


> Когда размер лога достиг ограничения


Сбрасываем его в архив и начинаем новый :)


 
Владислав ©   (2005-12-08 15:10) [14]


> Игорь Шевченко ©   (08.12.05 15:06) [13]
>
> > Когда размер лога достиг ограничения
>
>
> Сбрасываем его в архив и начинаем новый :)


Не пойдет :) Тогда придется нарисовать опции, в которых можно будет задавать каталог для архивов, ограничение на количество файлов в архиве, а я жутко не люблю делать интерфейс :) Уж лучше... даже не знаю... Лучше чего-нибудь придумать :)


 
Digitman ©   (2005-12-08 15:15) [15]


> Критика приветствуется


Скажи, а что ты все же под "сдвигом" подразумеваешь ?
Если копирование полного образа файла в АП процесса приложения и последующие Move-like-операции с памятью, то идея эта критику попросту не выдерживает - АП процесса не резиновое.

открываешь ReadFileStream,
делаешь соотв.расчеты,
открываешь WriteFileStream,
по результатам расчетов делаешь нужное смещение позиции в ReadFileStream отн-но начала,
выполняешь WriteFileStream.CopyFrom(ReadFileStream, вычисленный размер)
дозаписываешь в хвост WriteFileStream разделитель строк и саму строку
закрываешь оба стрима.


 
Владислав ©   (2005-12-08 15:21) [16]


> Digitman ©   (08.12.05 15:15) [15]
>
> > Критика приветствуется
>
>
> Скажи, а что ты все же под "сдвигом" подразумеваешь ?
> Если копирование полного образа файла в АП процесса приложения
> и последующие Move-like-операции с памятью


Ясен пень, что нет (мне, по крайней мере, ясен) :)

Пока два варианта.
1. MMF.
2. TFileStream.


 
Владислав ©   (2005-12-08 15:25) [17]

У меня вообще губа не дура. Меня вполне бы устроил вариант, если бы система поддерживала "зацикленные" файлы. Записали последний блок файла, система взяла и передвинула указатель начала файла на второй его блок, первый блок присоединила к концу файла и продолжила запись в уже новый последний блок.

:)

P.S.: Это не про windows, это фантастика :)


 
Digitman ©   (2005-12-08 15:34) [18]


> 1. MMF.


не выдерживает критики по той же причине - "нерезиновости" АП.


 
Владислав ©   (2005-12-08 15:38) [19]

Именно по причине "нерезиновости" АП TStream выделяет буфер максимальным размером $F000 для копирования? Я так тоже смогу :)
Кстати, а почему именно $F000? Магия?..


 
Digitman ©   (2005-12-08 15:47) [20]


>  а почему именно $F000? Магия?..


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

если кто-то и выделяет какие-то буферы, так это наследники TStream, каковым (непрямым) и является TFileStream .. но в теле TFileStream.Create нет ни намека ни на какие $F000


 
Digitman ©   (2005-12-08 15:50) [21]


> Я так тоже смогу


а зачем изобретать велосипед, если его уже изобрели в виде того же TFileStream ?

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


 
Владислав ©   (2005-12-08 15:55) [22]


> Digitman ©   (08.12.05 15:47) [20]
>
> >  а почему именно $F000? Магия?..
>
>
> а где ты такую цифирь узрел именно в реализации TStream
> ?


function TStream.CopyFrom(Source: TStream; Count: Int64): Int64;
const
 MaxBufSize = $F000;
...
 if Count > MaxBufSize then BufSize := MaxBufSize else BufSize := Count;
 GetMem(Buffer, BufSize);
 try
...
     Source.ReadBuffer(Buffer^, N);
     WriteBuffer(Buffer^, N);
...



> Digitman ©   (08.12.05 15:50) [21]
>
> нежели вероятность распределения там же непрерывного блока
> в сотни и тысячи мегабайт


Сергей, я же нигде не утверждал, что собираюсь проецировать весь файл ;)


 
umbra ©   (2005-12-08 16:00) [23]

$F000 = 4096 = странице памяти


 
umbra ©   (2005-12-08 16:03) [24]

прошу прощения, увлекся ;

$F000 = 61440 = 15 страниц памяти


правда, неясно, что из этого следует :)


 
Digitman ©   (2005-12-08 16:05) [25]


> Владислав ©   (08.12.05 15:55) [22]


Ах вон ты о чем)

Ну так, наверно, по той же самой (упомянутой) причине здесь 60к фигурирует... ровно 15 страниц (почему не 16 - у Борланда свои соображения на этот счет) ... общий размер не превышает гранулярности сегмента ... всё чин по чину) ..


> не утверждал, что собираюсь проецировать весь файл


да ну а смысл-то в чем - проектировать шматками ?

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


 
Anatoly Podgoretsky ©   (2005-12-08 16:12) [26]

16 страниц = 1 сегмент полный, но одна страница может использоваться в служебных целях, поэтому до меньшей величины.


 
Digitman ©   (2005-12-08 16:17) [27]


> Anatoly Podgoretsky ©   (08.12.05 16:12) [26]


у меня тоже эта мысль промелькнула


 
Игорь Шевченко ©   (2005-12-08 16:34) [28]

Владислав ©   (08.12.05 15:10) [14]


> Не пойдет :) Тогда придется нарисовать опции, в которых
> можно будет задавать каталог для архивов, ограничение на
> количество файлов в архиве, а я жутко не люблю делать интерфейс
> :) Уж лучше... даже не знаю... Лучше чего-нибудь придумать
> :)


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


 
Владислав ©   (2005-12-08 16:51) [29]

Игорь, из задачи же вроде бы ясно, что это: "Или просто два файла - один горячий, другой холодный и они меняются местами по заполнению" не подходит.


 
Игорь Шевченко ©   (2005-12-08 17:03) [30]

Владислав ©   (08.12.05 16:51) [29]

Мне из задачи видно, что ты хочешь странного :) Например, хочешь полную аналогию буфера экрана. Так для него алгоритмы давно известны и если очень хочется извратиться, то, сам понимаешь, адаптация их к некоему буферу фиксированного размера - дело рутинное. Плюс запись всего буфера целиков в файл по добавлению новой записи в лог.
Вопрос только в одном - а стоит ли овчинка выделки ? Сдается мне, что на скроллинг ты потратишь больше времени и нервов, чем на применение более простого решения.


 
WondeRu ©   (2005-12-08 17:09) [31]

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

че-нить вроде такого
procedure writelog(s: string)
var
 LogBlock: String[100];
begin
FillChar(@LogBlock,100," ");
LogBlock := s;
if Position > N
 then
   Position := 0
 else
   Inc(Position);

writeblocktoposition(Position * 100, LogBlock);//тут твоя функция записи в файл
end;


 
Владислав ©   (2005-12-09 14:25) [32]

Огромное спасибо всем за советы.
Вот что получилось в итоге.
Критика приветствуется ;)

unit LogFileU;

interface

uses
 Windows, Classes, SysUtils, Forms;

type

 ELogFileException = class(Exception);

 TLogFile = class(TObject)
 private
   FLogFileThread: Pointer;
   FStream: TFileStream;
   FReadStream: TFileStream;
   FFileName: string;
   FMaxSize: Integer;
   FDecreaseSize: Integer;
   FSilentExceptions: Boolean;              
 private
   procedure CreateLogStream;
   procedure FreeLogStream;
   function GetReadStream: TFileStream;
   procedure FreeReadStream;
   procedure SeekStreamToEnd;
   procedure SetFileName(const Value: string);
   procedure SetMaxSize(const Value: Integer);
   procedure CheckMaxSize(Increase: Integer);
   procedure CalculateDecreaseSize;
   procedure DecreaseLogStream;
   procedure WriteBuffer(const Buffer; Size: Integer);
   property ReadStream: TFileStream read GetReadStream;
   procedure RunLogFlush;
 public
   constructor Create(const AFileName: string; AMaxSize: Integer);
   destructor Destroy; override;
   procedure ClearLog;
   procedure Write(const AString: string);
   procedure WriteLine(const AString: string);
   property FileName: string read FFileName write SetFileName;
   property MaxSize: Integer read FMaxSize write SetMaxSize;
   property SilentExceptions: Boolean
     read FSilentExceptions write FSilentExceptions;
 end;


Продолжение следует...


 
Владислав ©   (2005-12-09 14:25) [33]

implementation

const
 EOL = ""#$0D#$0A"";
 ErrWhileEventWaitingMsg = "Log file thread waiting error";
 
function CloseAndNilHandle(var AHandle: THandle): Boolean;
var
 TempHandle: THandle;
begin
 TempHandle := AHandle;
 Result := TempHandle = 0;
 if not Result then
 begin
   AHandle := 0;
   Result := CloseHandle(TempHandle);
 end;
end;

type

 TLogFileThread = class(TThread)
 private
   FLogFile: TLogFile;
   FWorkEvent: THandle;
   FException: Exception;
   FLogChanged: Boolean;
 private
   procedure ShowException;
   procedure FlushLogFile;
 protected
   procedure Execute; override;
 public
   constructor Create(ALogFile: TLogFile);
   destructor Destroy; override;
   procedure StopAndWaitFor;
   procedure SetLogChanged;
 end;

{ TLogFileThread }

constructor TLogFileThread.Create(ALogFile: TLogFile);
begin
 FLogFile := ALogFile;
 FWorkEvent := CreateEvent(nil, False, False, nil);
 if FWorkEvent = 0 then
   Terminate;
 inherited Create(False);
 Priority := tpIdle;
end;

destructor TLogFileThread.Destroy;
begin
 CloseAndNilHandle(FWorkEvent);
 inherited;
end;

procedure TLogFileThread.Execute;
var
 WaitResult: DWORD;
begin
 try
   while not Terminated do
   begin
     WaitResult := WaitForSingleObject(FWorkEvent, INFINITE);
     if WaitResult = WAIT_OBJECT_0 then
     begin
       if not Terminated then
       begin
         if FLogChanged then
           Synchronize(FlushLogFile)
       end
       else
         Break;
     end
     else
       raise ELogFileException.Create(ErrWhileEventWaitingMsg);
   end;
 except
   on E: Exception do
   begin
     FException := E;
     Synchronize(ShowException);
   end
 end
end;

procedure TLogFileThread.FlushLogFile;
begin
 {$B-}
 if (FLogFile <> nil) and (FLogFile.FStream <> nil) then
   FlushFileBuffers(FLogFile.FStream.Handle);
 FLogChanged := False;
end;

procedure TLogFileThread.SetLogChanged;
begin
 if not FLogChanged then
 begin
   FLogChanged := True;
   if FWorkEvent <> 0 then
     SetEvent(FWorkEvent);
 end;
end;

procedure TLogFileThread.ShowException;
begin
 {$B-}
 if (FLogFile <> nil) and (not FLogFile.SilentExceptions) then
   Application.ShowException(FException);
end;

procedure TLogFileThread.StopAndWaitFor;
begin
 Terminate;
 if FWorkEvent <> 0 then
   SetEvent(FWorkEvent);
 Priority := tpNormal;
 WaitFor;
end;

{ TLogFile }

constructor TLogFile.Create(const AFileName: string; AMaxSize: Integer);
begin
 FSilentExceptions := True;
 FLogFileThread := TLogFileThread.Create(Self);
 MaxSize := AMaxSize;
 FileName := AFileName;
end;

destructor TLogFile.Destroy;
var
 Thread: TLogFileThread;
begin
 FreeReadStream;
 FreeLogStream;
 Thread := TLogFileThread(FLogFileThread);
 if Thread <> nil then
 begin
   Thread.StopAndWaitFor;
   FreeAndNil(Thread);
 end;
 inherited;
end;

procedure TLogFile.CreateLogStream;
begin
 if FStream = nil then
 begin
   if not FileExists(FFileName) then
     with TFileStream.Create(FFileName, fmCreate or fmShareDenyWrite) do
       Free;
   FStream := TFileStream.Create(FFileName, fmOpenReadWrite or fmShareDenyWrite);
 end;
 SeekStreamToEnd;
end;

procedure TLogFile.FreeLogStream;
begin
 FreeAndNil(FStream);
end;

procedure TLogFile.SeekStreamToEnd;
begin
 if FStream <> nil then
   FStream.Seek(0, soEnd);
end;

function TLogFile.GetReadStream: TFileStream;
begin
 if FReadStream = nil then
   FReadStream := TFileStream.Create(FFileName, fmOpenRead or fmShareDenyNone);
 Result := FReadStream;
end;

procedure TLogFile.FreeReadStream;
begin
 FreeAndNil(FReadStream);
end;

procedure TLogFile.RunLogFlush;
begin
 TLogFileThread(FLogFileThread).SetLogChanged;
end;

procedure TLogFile.ClearLog;
begin
 if FStream <> nil then
   FStream.Size := 0;
end;

procedure TLogFile.SetFileName(const Value: string);
begin
 if FFileName <> Value then
 begin
   FreeReadStream;
   FreeLogStream;
   FFileName := Value;
   CreateLogStream;
 end;
end;

procedure TLogFile.SetMaxSize(const Value: Integer);
begin
 if FMaxSize <> Value then
 begin
   FMaxSize := Value;
   if (FMaxSize > 0) and (FMaxSize < 1024) then
     FMaxSize := 1024;
   FMaxSize := ((FMaxSize + 1023) shr 10) shl 10;
   CalculateDecreaseSize;
   CheckMaxSize(0);
 end;
end;

procedure TLogFile.CalculateDecreaseSize;
var
 DecreaseSize: Integer;
begin
 if FMaxSize > 0 then
 begin
   DecreaseSize := FMaxSize shr 6;
   if DecreaseSize < 128 then
     DecreaseSize := 128;
 end
 else
   DecreaseSize := 0;
 FDecreaseSize := DecreaseSize;
end;

procedure TLogFile.DecreaseLogStream;
var
 LocalReadStream: TFileStream;
 SizeToMove: Int64;
 MoveFrom: Int64;
 Size: Int64;
begin
 if (FDecreaseSize > 0) and (FMaxSize > 0) then
 begin
   Size := FStream.Size;
   SizeToMove := FMaxSize - FDecreaseSize;
   MoveFrom := Size - SizeToMove;
   if MoveFrom > 0 then
   begin
     MoveFrom := ((MoveFrom + 3) shr 2) shl 2;
     SizeToMove := Size - MoveFrom;
     Size := SizeToMove;
     LocalReadStream := ReadStream;
     LocalReadStream.Seek(MoveFrom, soBeginning);
     FStream.Seek(0, soBeginning);
     FStream.CopyFrom(LocalReadStream, SizeToMove);
     FStream.Size := Size;
     SeekStreamToEnd;
   end;
 end;
end;

procedure TLogFile.CheckMaxSize(Increase: Integer);
begin
 if FStream <> nil then
 begin
   if FMaxSize > 0 then
   begin
     if FStream.Size + Increase > FMaxSize then
       DecreaseLogStream;
   end;
 end;
end;

procedure TLogFile.WriteBuffer(const Buffer; Size: Integer);
begin
 if FStream <> nil then
 begin
   CheckMaxSize(Size);
   FStream.Write(Buffer, Size);
   RunLogFlush;
 end;
end;

procedure TLogFile.Write(const AString: string);
var
 StrLen: Integer;
begin
 try
   if FStream <> nil then
   begin
     StrLen := Length(AString);
     if StrLen > 0 then
     begin
       CheckMaxSize(StrLen);
       WriteBuffer(Pointer(AString)^, StrLen)
     end;
   end;
 except
   on E: Exception do
   begin
     if not FSilentExceptions then
       raise;
   end;
 end;
end;

procedure TLogFile.WriteLine(const AString: string);
var
 StrLen: Integer;
 EolLen: Integer;
begin
 try
   if FStream <> nil then
   begin
     StrLen := Length(AString);
     EolLen := Length(EOL);
     CheckMaxSize(StrLen + EolLen);
     if StrLen > 0 then
       WriteBuffer(Pointer(AString)^, StrLen);
     WriteBuffer(EOL, EolLen);
   end;
 except
   on E: Exception do
   begin
     if not FSilentExceptions then
       raise;
   end;
 end;
end;

end.


 
Alexander Panov ©   (2005-12-09 14:40) [34]

Ну и тут посмотри... так... на всякий случай.
http://kladovka.net.ru/delphibase/?action=viewfunc&topic=fileini&id=10563


 
Владислав ©   (2005-12-09 15:07) [35]


> Alexander Panov ©   (09.12.05 14:40) [34]


Посмотрел. Идея понравилась. Где ж Вы раньше были? :)
Только не такой уж он безопасный.


 
Alexander Panov ©   (2005-12-09 15:20) [36]

Владислав ©   (09.12.05 15:07) [35]
Только не такой уж он безопасный.


Ну если есть места опасные, то сделай замечание;)


 
Владислав ©   (2005-12-09 15:26) [37]


> Alexander Panov ©   (09.12.05 15:20) [36]
>
> Ну если есть места опасные, то сделай замечание;)


Куда делать замечания?


 
Alexander Panov ©   (2005-12-09 15:28) [38]

Владислав ©   (09.12.05 15:26) [37]
Куда делать замечания?


Лучше здесь;)


 
Владислав ©   (2005-12-09 15:47) [39]

Будем оффтопить...

Разбор полетов курсанта... упс...
:)

Вот, в общем, то, что бросилось в глаза:

1).

constructor TPushPop.Create;
begin
// Нехватило памяти на следующем выделении
// Результат описан в деструкторе

 New(FRootItem);
...
destructor TPushPop.Destroy;
begin
// Вход в неинициализированную критическую секцию
 Lock;
// Обращение к указателю на нулевой адрес
   while FRootItem.Next<>FLastItem do DeleteItem0;
...
// Прочие варианты тоже можно спрогнозировать


2).

procedure TPushPop.Push(const Str: String);
var
 p: PItemList;
 pi: PChar;
begin
// Выделили память для хранения строки
 pi := AllocMem(Length(Str)+1);
 move(Str[1],pi^,Length(Str));
// Если на следующей строчке кода произошло исключение
// Память для хранения строки "улетела в никуда". Утечка.

 Lock;
 try
// Или здесь может возникнуть исключение.
// Память, выделенная для строки, тоже утечет

   New(p);


 
Игорь Шевченко ©   (2005-12-09 16:14) [40]

Владислав ©   (09.12.05 14:25) [33]


> function CloseAndNilHandle(var AHandle: THandle): Boolean;
>
> var
>  TempHandle: THandle;
> begin
>  TempHandle := AHandle;
>  Result := TempHandle = 0;
>  if not Result then
>  begin
>    AHandle := 0;
>    Result := CloseHandle(TempHandle);
>  end;
> end;


Народу непонятно, зачем нужна временная переменная.


>  FWorkEvent := CreateEvent(nil, False, False, nil);
>  if FWorkEvent = 0 then
>    Terminate;


А почему объект не создался, никого нафиг не интересует, верно ?


> destructor TLogFileThread.Destroy;
> begin
>  CloseAndNilHandle(FWorkEvent);
>  inherited;
> end;


Нафига, собственно, обнулять значение поля FWorkEvent в деструкторе ? Отмазки про наследников не катят - поле приватное :)


>   if FWorkEvent <> 0 then
>      SetEvent(FWorkEvent);


А эта проверка зачем ?
В конструкторе сделан страшный Terminate, если FWorkEvent = 0, поток, насколько я понимаю, выполняться не будет, Wait тоже не выполнится и SetEvent будет сделан впустую



Страницы: 1 2 вся ветка

Форум: "Основная";
Текущий архив: 2006.01.15;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.61 MB
Время: 0.015 c
14-1134839841
Piter
2005-12-17 20:17
2006.01.15
Хазанов


2-1135339132
KvORubin
2005-12-23 14:58
2006.01.15
Программеры подскажите (примером) КАК ПЕРЕСЛАТЬ ФАЙЛ??


2-1134741480
Scorpio
2005-12-16 16:58
2006.01.15
Работа с документами WORD


2-1135611497
kotbazilio
2005-12-26 18:38
2006.01.15
Удалить запись из таблицы


1-1134025349
cyborg
2005-12-08 10:02
2006.01.15
Обращение к переменным в потоках





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский