общий заблокированный пул, добавление общего в неуниверсальный список - PullRequest
0 голосов
/ 08 октября 2010

Я попробовал свои силы в общем классе, и со второй попытки я попытался создать общий закрытый пул. Я почти получил его на работу Я наткнулся на то место, где я хочу поместить типизированный класс в заблокированный tlist, полученный из tthreadlist.

Основной вопрос:

  • Кто-нибудь знает решение этой проблемы? (см. «проблемное место» в источнике)

Подсказки, второстепенные вопросы:

  • Нужно ли мне дополнительное ограничение, которое сигнализирует о ссылке? (Я попытался добавить ссылку на уже существующий класс и конструктор)
  • Знает ли 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 Ответ

2 голосов
/ 08 октября 2010

Используйте v.Add(TObject(x)) или, если вам нужно (возможно, это не сработает в 2009 году, мне неудобно проверять), v.Add(PPointer(@x)^).

...