Jee*_*dee 2 delphi multithreading
应用说明:
我有一个应用程序,允许用户通过线程运行多个并发查询(一次最多100个).
我有一个用于记录错误的类.如果应用程序中发生错误,我创建该类的实例并调用过程将错误写入日志文件.
题:
我需要使错误记录代码线程安全.我注意到如果很多线程同时运行并产生相同的错误(例如无法连接到数据库),我会收到i/o错误32(由于应用程序试图写入一个文件而导致已经开放).
作为一个快速而肮脏的修复,我将写入文件的代码放入try ...除了重复循环内的块之外.如果存在异常(例如,该文件已被该类的另一个实例打开,由另一个线程启动),则它将标志设置为"false".循环继续执行,直到标志为"true"(即没有错误写入文件),如下所示:
procedure TErrorLogging.logError(error: string);
var
f: textfile;
ok: boolean;
begin
repeat
ok := true;
try
assignfile(f, fLogFilename);
if fileExists(fLogFilename) then append(f) else rewrite(f);
writeln(f, error);
closefile(f);
except
ok := false;
end;
until ok;
end;
Run Code Online (Sandbox Code Playgroud)
我知道保护代码块的正确方法是使用Critical Sections,但我不确定如何实现它,因为有许多不同的线程使用了日志记录类,并且每个实例该线程有自己的日志记录类实例,它用于写入文件(因此它们不仅仅是针对同一代码块进行同步).
选项,我可以看到它们:
每当要添加日志条目时创建日志记录类的实例都是错误的,并且反复打开和关闭日志文件.我个人会使用一个类的一个实例,它在内部使用一个字符串列表,其基本方法是线程安全的.像这样的东西:
type
TErrorLog = class
private
FList: TStringList;
FLock: TRTLCriticalSection;
public
constructor Create;
destructor Destroy; override;
procedure Clear;
procedure Add(const ErrorText: string);
procedure SaveToFile(const FileName: string);
end;
implementation
{ TErrorLog }
constructor TErrorLog.Create;
begin
inherited Create;
InitializeCriticalSection(FLock);
FList := TStringList.Create;
end;
destructor TErrorLog.Destroy;
begin
EnterCriticalSection(FLock);
try
FList.Free;
inherited Destroy;
finally
LeaveCriticalSection(FLock);
DeleteCriticalSection(FLock);
end;
end;
procedure TErrorLog.Clear;
begin
EnterCriticalSection(FLock);
try
FList.Clear;
finally
LeaveCriticalSection(FLock);
end;
end;
procedure TErrorLog.Add(const ErrorText: string);
begin
EnterCriticalSection(FLock);
try
FList.Add(ErrorText);
finally
LeaveCriticalSection(FLock);
end;
end;
procedure TErrorLog.SaveToFile(const FileName: string);
begin
EnterCriticalSection(FLock);
try
FList.SaveToFile(FileName);
finally
LeaveCriticalSection(FLock);
end;
end;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1175 次 |
| 最近记录: |