【问题标题】:Can I declare TCriticalSection object as a public class field?我可以将 TCriticalSection 对象声明为公共类字段吗?
【发布时间】:2013-11-29 15:47:33
【问题描述】:

能否将TCriticalSection 对象声明为公共字段,例如:

type
  TMyObject = class
  public
    CS: TCriticalSection;
  end;

我想公开该字段以允许任何线程进入和离开临界区对象,这在内部保护TMyObject 实例的完整性。那么,我可以将TCriticalSection 对象声明为公共类字段吗?

【问题讨论】:

  • 我会创建像LockObject、UnlockObject 这样的公共方法,它们将在内部进入和离开私有临界区对象。这是常见的时尚。
  • 查看 TThreadList 中的完成方式,例如,它具有 LockList 和 UnlockList 方法。

标签: delphi critical-section


【解决方案1】:

简单的答案是肯定的。类的字段是存放TCriticalSection 的完全正常的地方。

为了使临界区能够序列化对共享资源的访问,所有线程必须引用临界区的同一个实例。因此,根据这一事实,您得出结论,您需要确保所有线程都引用该类的同一实例。然后,当他们读取该类的临界区字段时,所有线程都在访问临界区的同一个实例。

通常认为声明公共字段是不好的做法。您通常会通过类的属性或方法公开此类内容。

【讨论】:

  • 完全同意。我宁愿简单地公开公共 Lock 和 Unlock 方法。
【解决方案2】:

这是我过去为实现这一目标所做的:

  TMyObject = class(TObject)
  private
    FCS                 :TCriticalSection;
    FMyProp             :string;
    function GetMyProp :string;
    procedure SetMyProp( const NewValue :string );
  protected
  public
    constructor Create;
    destructor Destroy; override;
    // properties
    property MyProp :string read GetMyProp write SetMyProp;
  end;

接着是实现:

constructor TMyObject.Create;
begin
  inherited Create;
  FCS     := TCriticalSection.Create;
  FMyProp := '';
end;

destructor TMyObject.Destroy;
begin
  FCS.Free;
  inherited Destroy;
end;

function TMyObject.GetMyProp :string;
begin
  FCS.Enter;
  try
    result := FMyProp;
  finally
    FCS.Leave;
  end;
end;

procedure TMyObject.SetMyProp( const NewValue :string );
begin
  FCS.Enter;
  try
    FMyProp := NewValue;
  finally
    FCS.Leave;
  end;
end;

请注意,我没有公开 FCS 字段。

【讨论】:

  • @TLama:我同意你的说法,并更新了答案。也就是说,我以前的版本从来没有任何问题。
  • 过去从未失败过这一事实毫无意义。它坏了。如果Enter 失败,那么您将调用Leave,这是错误的。现在,Enter 可能永远不会失败,但这无关紧要。将尝试放在正确的位置很重要。 在成功获取资源后立即。
  • @David:是的,我同意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-09-20
  • 2019-09-09
  • 2016-01-29
  • 1970-01-01
  • 1970-01-01
  • 2018-11-12
  • 2021-04-19
相关资源
最近更新 更多