我已经构建了一个简单的日志类,并且想确认它是线程安全的。基本上Log
,RegisterLogger
和UnRegisterLogger
将被从不同的线程调用。 Log
将被称为很多(从许多不同的线程)和RegisterLogger
和UnRegisterLogger
很少。德尔福阅读TList <x>线程安全吗?
基本上我的问题可以归结为:“TList<x>
线程安全吗?”,也就是说我可以有多个线程在同一时间访问TList
。
IExecutionCounterLogger
是与登录方法的接口(与相同的签名TExecutionCounterServer.Log
)
Type
TExecutionCounterServer = class
private
Loggers : TList<IExecutionCounterLogger>;
Synchronizer : TMultiReadExclusiveWriteSynchronizer;
public
procedure RegisterLogger(Logger : IExecutionCounterLogger);
procedure UnRegisterLogger(Logger : IExecutionCounterLogger);
procedure Log(const ClassName, MethodName : string; ExecutionTime_ms : integer);
constructor Create;
destructor Destroy; override;
end;
constructor TExecutionCounterServer.Create;
begin
Loggers := TList<IExecutionCounterLogger>.Create;
Synchronizer := TMultiReadExclusiveWriteSynchronizer.Create;
end;
destructor TExecutionCounterServer.Destroy;
begin
Loggers.Free;
Synchronizer.Free;
inherited;
end;
procedure TExecutionCounterServer.Log(const ClassName, MethodName: string; ExecutionTime_ms: integer);
var
Logger: IExecutionCounterLogger;
begin
Synchronizer.BeginRead;
try
for Logger in Loggers do
Logger.Log(ClassName, MethodName, ExecutionTime_ms);
finally
Synchronizer.EndRead;
end;
end;
procedure TExecutionCounterServer.RegisterLogger(Logger: IExecutionCounterLogger);
begin
Synchronizer.BeginWrite;
try
Loggers.Add(Logger);
finally
Synchronizer.EndWrite;
end;
end;
procedure TExecutionCounterServer.UnRegisterLogger(Logger: IExecutionCounterLogger);
var
i : integer;
begin
Synchronizer.BeginWrite;
try
i := Loggers.IndexOf(Logger);
if i = -1 then
raise Exception.Create('Logger not present');
Loggers.Delete(i);
finally
Synchronizer.EndWrite;
end;
end;
作为比特更多的背景,这是从一个this question跟随上。基本上,我已经为(DCOM)DataSnap服务器的每种方法添加了一些工具,我也已经将其添加到每个TDataSnapProvider OnGetData和OnUpdateData事件中。
同步器是TMultiReadExclusiveWriteSynchronizer –
也许我没有得到正确的问题。使用同步器显然是线程安全的(多数民众赞成在整个目的)。我明白阿利斯特,他希望省略阅读部分。 –
不,Alister询问当多个“阅读器”将同时运行时,TList阅读是否能够正常工作。 –
gabr