代码之家  ›  专栏  ›  技术社区  ›  Marco van de Voort

通用锁定池,将通用添加到非通用tlist

  •  0
  • Marco van de Voort  · 技术社区  · 14 年前

    我在一个通用类中尝试了我的手,第二次尝试时,我尝试了创建一个通用锁定池。我差一点就要开始工作了 我偶然发现了一个地方,我想把一个泛型类型的类放入一个从tthreadlist获得的锁定tlist中。

    主要问题是:

    • 有人知道这个问题的解决办法吗?(见来源中的“问题点”)。

    提示、次要问题:

    • 我是否需要一个额外的信号引用约束?(我尝试添加,引用已经存在的类和构造函数)
    • sb是否了解所有“特殊”泛型约束(类、构造函数)的良好概述页面?在手册中找不到太多。
    • 公司在D2009,但我有一个用于迁移准备的单一许可证DXE。

    这个池使用的对象是对象,更糟糕的是,其中一些对象有一些必须内联的关键方法。(这是一个图像处理应用程序,这也是为什么我不那么关心相对简单的锁。粒度较粗)。我提到这一点,因为它可能会使基于接口的解决方案变得困难。

    type
         TLockedPool<T:class,constructor>   =   class
                                      private
                                        lst : tthreadlist;
                                      public
                                        type sometype =t;  // part of workarounds.
                                        destructor  destroy;
                                        constructor create;
                                        function    getitem:T;
                                        procedure   putitem(var b:T);
                                       end;
    
     constructor TLockedPool<T>.create;
     begin
      lst:=TThreadlist.Create;
     end;
    
    destructor TLockedPool<T>.destroy;
    var i : integer;
        v: tlist;
    begin
      v:=lst.locklist;
      for i:=0 to v.count-1 do
        Tobject(v[i]).Free;
      lst.unlocklist;
      v.clear;
      freeandnil(lst);
     inherited;
    end;
    
    function TLockedPool<T>.getitem: T;
    var cnt:integer;
       v : tlist;
    begin
      v:=lst.LockList;
      cnt:=v.Count;
      if cnt>0 then
        begin
          result:=tobject(v[cnt-1]);
          v.delete(cnt-1);
        end
      else
        begin
         result:=T.create;
        end;
      lst.UnlockList;
    end;
    
    procedure TLockedPool<T>.putitem(var b: T);
    var  v : Tlist;
     x : sometype;
    begin
    if assigned(b) then // some older parts of the framework are dirty and try to put in NILs.
        begin
          v:=lst.LockList;
          x:=b;
          v.Add(pointer(sometype(x)));  // <--- the problemspot
          lst.unlocklist;
        end;
     b:=nil;
    end;
    
    1 回复  |  直到 14 年前
        1
  •  2
  •   Barry Kelly    14 年前

    v.Add(TObject(x)) v.Add(PPointer(@x)^)