我已經構建了一個簡單的日誌類,並且想確認它是線程安全的。基本上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