Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 如何使用Indy10中的TIdThreadSafe类_Delphi_Indy - Fatal编程技术网

Delphi 如何使用Indy10中的TIdThreadSafe类

Delphi 如何使用Indy10中的TIdThreadSafe类,delphi,indy,Delphi,Indy,如果我定义了一个新类,我可以使用Indy命令TIdThreadSafe使一个类成为MyPrivateClass threadsafe吗 MyNewIndyClass = Class(TIdThreadSafe) FLocal : MyPrivateClass create ...... end; 我的MyPrivateClass不是线程安全的,因为我访问该类中的TList和TBitmap项 如果我将TCPSe

如果我定义了一个新类,我可以使用Indy命令TIdThreadSafe使一个类成为MyPrivateClass threadsafe吗

   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,如果你觉得这很有用,并且回答了你的问题,请不要忘记接受它作为答案