gpt4 book ai didi

delphi - 如何使用 Indy10 中的 TIdThreadSafe 类

转载 作者:行者123 更新时间:2023-12-03 15:55:04 24 4
gpt4 key购买 nike

如果我定义一个新类,我可以使用 Indy 命令 TIdThreadSafe 使类 MyPrivateClass 线程安全

   MyNewIndyClass = Class(TIdThreadSafe)
FLocal : MyPrivateClass
create
......
end;

我的 MyPrivateClass 不是线程安全的,因为我访问此类中的 TList 和 TBitmap 项

如果我将 TCPServer.Oneexecutde 代码更改为以下样式

    ......

aNewIndyClass := MyNewIndyClass.Create;

aNewIndyClass.FLocal.CallFuntionA;

aNewIndyClass.FLocal.CallFuntionB;

......

这种方法的想法:保持 MyPrivateClass 代码不变,只需在单独的类中添加对 Indy Server onexecute 的请求

最佳答案

您应该使用 TIdThreadSafe 类的 Lock() 和 Unlock() 方法。例如,在 TCPServer.OnExecute() 中调用 aNewIndyClass 的方法,如下所示:

  aNewIndyClass  :=  MyNewIndyClass.Create; 

aNewIndyClass.Lock; // This will enter TIdThreadSafe internal's Critical Section object
try
with aNewIndyClass do // The code between try/finally will be "atomic"
begin // i.e. no other thread will be able to do anything with your object
...
FLocal.CallFuntionA;
FLocal.CallFuntionB;
...
end;
finally // The use of TRY/FINALLY is MANDATORY when working with critical sections!
aNewIndyClass.Unlock; // This will leave the CS
end;

此外,最好使用属性(即 getter/setter)来访问 MyNewIndyClass 类的私有(private)或 protected 成员。

顺便说一句,如果您使用 Delphi 2009 及更高版本,您可以利用泛型。通用线程安全类的一个简短示例实现可能是:

  tThreadSafeObject<T: class> = class
private
fObject: T;
fCriticalSection: tCriticalSection;
public
constructor Create(cpObject: T); // We expect previously created object here. We own it!
// TODO: Implement ownership option?
destructor Destroy;
function Lock: T;
procedure Unlock;
end;

{ tThreadSafe<T> }

constructor tThreadSafeObject<T>.Create(cpObject: T);
begin
inherited Create;
fObject := cpObject;
fCriticalSection := TCriticalSection.Create;
end;

destructor tThreadSafeObject<T>.Destroy;
begin
FreeAndNil(fObject); // In this sample implementation fObject is owned so we free it
FreeAndNil(fCriticalSection);
inherited Destroy;
end;

function tThreadSafeObject<T>.Lock: T;
begin
fCriticalSection.Enter;
result := fObject;
end;

procedure tThreadSafeObject<T>.Unlock;
begin
fCriticalSection.Leave;
end;

用法:

procedure foo;
var
tsObj: tThreadSafeObject<tMyClass>;
begin
tsObj := tThreadSafeObject<tMyClass>.Create(tMyClass.Create);
try // In real World tsObj would be variable, accessed by different threads
with tsObj.Lock do
try
// Do some atomic stuff here
finally
tsObj.Unlock;
end;
finally
freeAndNil(tsObj);
end
end;

关于delphi - 如何使用 Indy10 中的 TIdThreadSafe 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13111880/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com