Формы и процессы
Но при закрытии формы, которая в библиотеке, поток продолжает выполнятся (это видно в ProcessExplorer). Если я пытаюсь прибить дочерний поток из основного руками:
Thread.Doterminate();
Thread.Destroy();
То вылетает исключение о неверном дескрипторе потока. Причем при выполнении метода DoTerminate, происходят странные вещи: функция DLLMain из библиотеки возвращает следующие события:
THREAD_ATTACH, потом THREAD_DETACH (именно в такой последовательности).
Как быть?
Такая задача: форма упрятана в библиотеку. В основной программе библиотека подгружется в отдельном потоке (стандартный делфевый TThread) и там работает.
Но при закрытии формы, которая в библиотеке, поток продолжает выполнятся (это видно в ProcessExplorer). Если я пытаюсь прибить дочерний поток из основного руками:
Thread.Doterminate();
Thread.Destroy();
То вылетает исключение о неверном дескрипторе потока. Причем при выполнении метода DoTerminate, происходят странные вещи: функция DLLMain из библиотеки возвращает следующие события:
THREAD_ATTACH, потом THREAD_DETACH (именно в такой последовательности).
Как быть?
А ты закрываеш форму или уничтожаеш?
Если ты просто закроеш, то она ведь останется висеть
Наконец-то получилось прибить поток из основного процесса. Но выгрузить библиотеку не получается - вылетает исключение.
Форму я закрываю. М она уничтожается (вызывается OnDestroy). VCL по описанию Борланда не является потокобезопасной, но сами они рекомендуют работать с ней через стандартный поток TThread.
Наконец-то получилось прибить поток из основного процесса. Но выгрузить библиотеку не получается - вылетает исключение.
Попытайся использовать монитор (TMonitor) для доступа к форме. Или заключи процедуры уничтожения окна в критическую секцию:
uses Windows;
var CS:CRITICAL_SECTION;
//TryEnterCriticalSection(CS);
EnterCriticalSection(CS);
//Забивай форму
LeaveCriticalSection(CS);
Попытайся использовать монитор (TMonitor) для доступа к форме. Или заключи процедуры уничтожения окна в критическую секцию:
uses Windows;
var CS:CRITICAL_SECTION;
//TryEnterCriticalSection(CS);
EnterCriticalSection(CS);
//Забивай форму
LeaveCriticalSection(CS);
В делфях есть класс такой TCriticalSection в модуле SynchObjs. У него методы есть Enter и Leave - какраз это самое и инкапсулируют
Такая задача: форма упрятана в библиотеку. В основной программе библиотека подгружется в отдельном потоке (стандартный делфевый TThread) и там работает.
Но при закрытии формы, которая в библиотеке, поток продолжает выполнятся (это видно в ProcessExplorer). Если я пытаюсь прибить дочерний поток из основного руками:
Thread.Doterminate();
Thread.Destroy();
То вылетает исключение о неверном дескрипторе потока. Причем при выполнении метода DoTerminate, происходят странные вещи: функция DLLMain из библиотеки возвращает следующие события:
THREAD_ATTACH, потом THREAD_DETACH (именно в такой последовательности).
Как быть?
А тут кажется кто-то говорил, что нельзя создать форму в параллельном потоке?
Вот примерный код создания окна в параллельном потоке (в библиотеке):
uses
SysUtils,
Classes,
Forms,
Unit2 in 'Unit2.pas' {Form2};
{$R *.res}
type
TDllThread = class(TThread)
protected
procedure Execute; override;
end;//of class
procedure TDllThread.Execute;
var Application: TApplication;
begin
Application:=TApplication.Create(nil);
Application.Initialize;
Application.CreateForm(TForm2,Form2);
Application.Run;
Application.Free;
end;
procedure StartThread; stdcall; export;
begin
with TDllThread.Create(true) do begin
FreeOnTerminate:=true;
Resume;
end;
end;
exports
StartThread;
end.
Вызываешь StartThread и появится окошко. При закрытии окошка поток сам умррёть.
А тут кажется кто-то говорил, что нельзя создать форму в параллельном потоке?
Если это обо мне - то ты не совсем прав...
Все дело может быть в том, что VCL не поддерживает параллельные потоки и создание форм в другом потоке - ИМХО тухлое дело
Не поддерживает и невозможно - совсем таки разные вещи.
Дело как раз в том, что создание форм VCL в паралельном потоке очень даже возможно (еще бы - ведь VCL фактически использует WinAPI), НО! никакой поддержки паралельных потоков в VCL нет, отсюда могут возникнуть очень даже замечательные проблемы. Так что...
Вызываешь StartThread и появится окошко. При закрытии окошка поток сам умррёть.
Поток живее всех живых. :( Вот только добрался до работы, переместил код создания потока в библиотеку. Окно создается, потом я его закрываю, но поток отстается.
Поток живее всех живых. :( Вот только добрался до работы, переместил код создания потока в библиотеку. Окно создается, потом я его закрываю, но поток отстается.
Просто когда форма закрывается нужно завершить выполнение того экземпляра Application, что создаётся в потоке.
т.е. надо передать в форму ссылку на тот Application и вызвать в событии OnClose Application.Terminate;
кроме того, чтоб не появлялась отдельная кнопка для формы попробуй сделать так:
SetWindowLong(Application.Handle, GWL_EXSTYLE, WS_EX_TOOLWINDOW);
Вставить это надо перед созданием формы.
Так написано же - Application.Free Что завершать тогда? Если приложения уже нет?
Ты не знаешь механизма работы TApplication.
Когда мы вызываем Application.Run то запускается цикл получения сообщений от системы. Этот цикл не прерывается в отдельном потоке. Мы должы послать Terminate сигнал, чтоб Run вернула управление. Поэтому нужно в обаботчике OnClose нашей формы искусственнно вызвать Terminate.