Я только что написал свой собственный каркас логирования (очень легкий, нет необходимости в большом каркасе логирования). Он состоит из интерфейса ILogger и ряда классов, реализующих этот интерфейс. Вопрос, о котором у меня есть вопрос, - это TGUILogger, который принимает TStrings в качестве цели ведения журнала и синхронизирует запись в журнал с основным потоком, так что элемент Items списка может использоваться в качестве цели.
type
ILogger = Interface (IInterface)
procedure Log (const LogString : String; LogLevel : TLogLevel);
procedure SetLoggingLevel (LogLevel : TLogLevel);
end;
type
TGUILogger = class (TInterfacedObject, ILogger)
public
constructor Create (Target : TStrings);
procedure Log (const LogString : String; LogLevel : TLogLevel);
procedure SetLoggingLevel (LogLevel : TLogLevel);
private
procedure PerformLogging;
end;
procedure TGUILogger.Log (const LogString : String; LogLevel : TLogLevel);
begin
TMonitor.Enter (Self);
try
FLogString := GetDateTimeString + ' ' + LogString;
TThread.Synchronize (TThread.CurrentThread, PerformLogging);
finally
TMonitor.Exit (Self);
end;
end;
procedure TGUILogger.PerformLogging;
begin
FTarget.Add (FLogString);
end;
Ведение журнала работает, но приложение не закрывается должным образом. Кажется, висит в блоке классов. Трассировка стека:
System.Halt0, System.FinalizeUnits, Classes.Finalization, Classes.FreeExternalThreads,
System.TObject.Free, Classes.TThread.Destroy, Classes.TThread.RemoveQueuedEvents
Что я здесь не так делаю?
РЕДАКТИРОВАТЬ: я только что нашел следующую подсказку в справке Delphi для TThread.StaticSynchronize
Warning: Do not call StaticSynchronize from within the main thread. This can cause
an infinite loop.
Это может быть именно моей проблемой, так как некоторые запросы на регистрацию поступают из основного потока. Как я могу решить это?