Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Приостановака потока.


Автор: Ryoga 25.5.2006, 11:26
Значит, есть две формы A и B. Также (в форме A) определён поток T и единственный его метод - Execute.
Создаётся поток при нажатии на кнопку в форме A. Происходит, скажем так, сопоставление объектов из базы данных. Если такого объекта в базе нет, то процесс T приостанавливается - Suspend. При этом мы можем вручную, на форме A выбрать нужный объект из дерева, после чего нажать на кнопку "продожить" - вызывается
Код

A.T.Resume();
 и конвертация проходит дальше, ничего не зависает.
Теперь понадобилось при конвертации сопоставлять кучу параметров, которые на форму A уже не влезают. Была создана форма B, в которой эти параметры можно выбрать. В проток T добален код
Код

if(no_parameters) then
begin
  B.Set_Par(Parameters_list); //передаём параметры в форму B
  B.Visible:=True;//выводим окно
  A.T.Suspend;//приостанавливаем поток
end;

При закрытии формы предполагается вызов A.T.Resume(), но
всё благополучно зависает при выводе формы. smile
Опеределил я в форме B метод и сделал, чтобы он вызывался по сообщению.
Код

procedure SetVisual(var Message); message WM_USER+111;
в коде метода только B.Visible:=True;

Поток T исправил на
Код

if(no_parameters) then
begin
  B.Set_Par(Parameters_list); //передаём параметры в форму B
  SendMessage(B.Handler,WM_USER+111,0,0);//выводим окно
  A.T.Suspend;//приостанавливаем поток
end;

Думал зависать не будет, но оно всё равно зависает. Почему так происходит? 

Автор: Rouse_ 25.5.2006, 15:04
Не понял, ты из потока к объектам формы обращаешся? Если да, то необходима синхронизация... 

Автор: Ryoga 25.5.2006, 18:03
Ну да, я обращаюсь из потока к объектам и методам форм, в том числе и той, в которой он был создан (форма A). Всё было хорошо, пока я не попытался показать форму B и что-нибудь из неё выбрать, приостановив поток, созданный в форме A. В каком месте необходима синхронизация?
З.Ы.: С названием темы напортачил. smile  

Автор: Демо 25.5.2006, 18:09
Цитата(Ryoga @  25.5.2006,  18:03 Найти цитируемый пост)
В каком месте необходима синхронизация?


В тех, где ты обращаешься к объектам основного потока. 

Автор: Rouse_ 25.5.2006, 20:46
Дополню, не только к методам но и к памяти (не важно объект, переменная, константа, метод или еще что-то там храниться), которая выделена не тем потоком из которого идет обращение... 

Автор: bems 25.5.2006, 21:30
Цитата(Rouse_ @  25.5.2006,  20:46 Найти цитируемый пост)
Дополню, не только к методам но и к памяти (не важно объект, переменная, константа, метод или еще что-то там храниться), которая выделена не тем потоком из которого идет обращение...  
Ну до этих глюков еще добраться нужно, а для начала все обращения к объектам VСL из потока делай с помощью TThread.Synchronize 
 

Автор: BinaryEvil 28.5.2006, 19:43
ключевые слова по синхронизации: mutex, criticalSection
раз форма не отвечает, значит ты не правильно поток аформил - у тебя все происходит в потоке самой формы. хоть это и неправильно, но лично я обхожусь в подобных ситуациях просто application.proccessmessages (цикл get/translate/dispatchmessage), без каких либо потоков... 

Автор: Ryoga 7.6.2006, 13:15
Так, я почитал статью выше и ещё кое-что... smile
Как я понимаю, параметром synchronize может быть только функция без параметров?
Ну, я взял и определил функцию, в которой у меня выполняется всё, что раньше было в Execute.
Теперь код выглядит так.
Код

TMyThread.Execute
begin
  Synchronize(Pro);
end;

TMyThread.Pro
var
  //бла бла бла
begin
  //а здесь весь код, который был в Execute
  MyForm.SetParameters(some parameters);//передача параметров в форму
  MyForm.Show;//вывод её на экран, когда надо
  MyThread.Suspend;//приостановка потока
  //и ещё куча всего. просто эти функции, как мне кажется, без синхронизации или ещё чего, и 
  //обеспечивали неправильную работу моей программы.
end;

Так вот, синхронизация вызова Pro означает ли, что у меня синхронизировано всё, что выполняется в этой процедуре?
В принципе, баги с зависанием и вылетом на экран сообщения "Неверный дескриптор формы" после определённых действий, после того, как я исправил программу вышеуказанным образом прекратились. Но я всё ещё не уверен - было ли это решением проблемы. 

Автор: Демо 7.6.2006, 14:09
Ryoga, 
Категорически неверно.

в Synchronize нужно толкьо обращение к общим объектам обертывать.
Все остальные расчеты должны вестись в Execute.

Особенность Synchronize - функция, которая передается в качестве параметра, выполняется в контексте основного потока. 

Автор: Ryoga 7.6.2006, 15:17
То есть, и остановка то потока не произойдёт, когда надо, т.к. всё идёт в другом потоке, получается?
Ну хорошо. А если написать так?

Код

TMyThread.SetPar
begin
  MyForm.SetParameters(some parameters);//передача параметров в форму
  MyForm.Show;//вывод её на экран
end;

TMyThread.Execute
var
  some_parameters;
begin
  some_parameters := Calculate();//расчитываем параметры
  Synchronize(SetPar);//устанавливаем то, что посчитали в форме
  MyThread.Suspend;//приостановка потока
end;

Теперь синхронизация только, когда устанавливаем параметры в другой форме и выводим её на экран.
 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)