Delphi 如何使用Indy10中的TIdThreadSafe类
如果我定义了一个新类,我可以使用Indy命令TIdThreadSafe使一个类成为MyPrivateClass threadsafe吗Delphi 如何使用Indy10中的TIdThreadSafe类,delphi,indy,Delphi,Indy,如果我定义了一个新类,我可以使用Indy命令TIdThreadSafe使一个类成为MyPrivateClass threadsafe吗 MyNewIndyClass = Class(TIdThreadSafe) FLocal : MyPrivateClass create ...... end; 我的MyPrivateClass不是线程安全的,因为我访问该类中的TList和TBitmap项 如果我将TCPSe
MyNewIndyClass = Class(TIdThreadSafe)
FLocal : MyPrivateClass
create
......
end;
我的MyPrivateClass不是线程安全的,因为我访问该类中的TList和TBitmap项
如果我将TCPServer.Onexecutde代码更改为以下样式
......
aNewIndyClass := MyNewIndyClass.Create;
aNewIndyClass.FLocal.CallFuntionA;
aNewIndyClass.FLocal.CallFuntionB;
......
这种方法的想法是:保持MyPrivateClass代码不变,只需在单独的类中添加对Indy Server OneExecute的请求您应该使用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类的私有或受保护成员
顺便说一下,如果您使用的是Delphi2009及更新版本,您可以利用泛型。通用线程安全类的一个简短示例实现可能是:
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;
tThreadSafeObject=class
私有的
对象:T;
fCriticalSection:tCriticalSection;
公众的
构造函数创建(cpObject:T);//我们期望在此之前创建的对象。我们拥有它!
//TODO:实现所有权选项?
毁灭者毁灭;
功能锁:T;
程序解锁;
结束;
{tThreadSafe}
构造函数tThreadSafeObject.Create(cpObject:T);
开始
继承创造;
foobject:=cpObject;
fCriticalSection:=TCriticalSection.Create;
结束;
析构函数tThreadSafeObject.Destroy;
开始
FreeAndNil(fObject);//在这个示例实现中,fObject是私有的,因此我们将其释放
FreeAndNil(关键路段);
继承性破坏;
结束;
函数tThreadSafeObject.Lock:T;
开始
fCriticalSection.Enter;
结果:=fObject;
结束;
程序tThreadSafeObject.Unlock;
开始
关键部分。离开;
结束;
用法:
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;
程序foo;
变量
tsObj:tthreadsafetobject;
开始
tsObj:=tThreadSafeObject.Create(tMyClass.Create);
try//在现实世界中,tsObj是可变的,由不同的线程访问
用tsObj.锁做
尝试
//在这里做一些原子的东西
最后
tsObj.解锁;
结束;
最后
freeAndNil(tsObj);
结束
结束;
该解决方案已经在我的计算机上运行,现在可以执行更多操作tests@user1769184,如果你觉得这很有用,并且回答了你的问题,请不要忘记接受它作为答案