Объект из bpl в потоке
Голова пухнет уже.
Дано:
- В package.bpl есть некий TPersistent.
- Требуется создать его объект в потоке.
- Без потоков он создаётся и отлично работает.
- Так же без проблем он создаётся и работает под отладкой. То есть трассировка и логи показывают, что всё нормально происходит.
- При этом, под отладкой он работает только если поставить брекпоинт на TPersistentClass.Create или до него и пошагово всё посмотреть.
- В run-time он просто не создаётся, exception такой: Canvas does not allow drawing
Код:
HP := LoadPackage(pName);
if HP > 0 then
begin
gClass := TgClass(GetClass(bla-bla));
if Assigned(gClass) then
begin
try
P := gClass.Create(Application);
SetEvent(P, 'OnError', Form1, 'ErrorMsg');
SetEvent(P, 'OnSuccess', Form1, 'AccessMsg');
SetObjectProp(P, 'Ini', PluginIni);
if Assigned(P) then
PAddr := P.MethodAddress('DoBlaBla');
if PAddr <> nil then
begin
M.Code := PAddr;
M.Data := Form1;
TDoBlBla(M);
end;
except
on E: Exception do
Form1.ErrorMsg(Self,
Format('%s. Do not create %s', [E.Message, pName]));
end;
if HP > 0 then
begin
gClass := TgClass(GetClass(bla-bla));
if Assigned(gClass) then
begin
try
P := gClass.Create(Application);
SetEvent(P, 'OnError', Form1, 'ErrorMsg');
SetEvent(P, 'OnSuccess', Form1, 'AccessMsg');
SetObjectProp(P, 'Ini', PluginIni);
if Assigned(P) then
PAddr := P.MethodAddress('DoBlaBla');
if PAddr <> nil then
begin
M.Code := PAddr;
M.Data := Form1;
TDoBlBla(M);
end;
except
on E: Exception do
Form1.ErrorMsg(Self,
Format('%s. Do not create %s', [E.Message, pName]));
end;
Что может быть причиной такого затейливого поведения?
А разве наследники TPersistent является threadsafe?
Ну там на самом деле наследыш TForm лежит. TPersistent я указал как самый верхний, который можно указать для RegisterClass.
Во ещё обнаружилось что: срабатывает, но как-то случайно и иногда. Примерно один раз из четырёх-пяти ошибочных. мистика какая-то!
Цитата: mfender
Ну там на самом деле наследыш TForm лежит. TPersistent я указал как самый верхний, который можно указать для RegisterClass.
так какая разница - это понятно что объект самого класса создавать нельзя - но сам факт - разве VCL-компоненты стали потокобезопасны?
Код:
P := gClass.Create(Application);
SetEvent(P, 'OnError', Form1, 'ErrorMsg');
SetEvent(P, 'OnSuccess', Form1, 'AccessMsg');
SetObjectProp(P, 'Ini', PluginIni);
if Assigned(P) then
PAddr := P.MethodAddress('DoBlaBla');
if PAddr <> nil then
begin
M.Code := PAddr;
M.Data := Form1;
TDoBlBla(M);
end;
SetEvent(P, 'OnError', Form1, 'ErrorMsg');
SetEvent(P, 'OnSuccess', Form1, 'AccessMsg');
SetObjectProp(P, 'Ini', PluginIni);
if Assigned(P) then
PAddr := P.MethodAddress('DoBlaBla');
if PAddr <> nil then
begin
M.Code := PAddr;
M.Data := Form1;
TDoBlBla(M);
end;