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


Автор: Albinos_x 28.12.2005, 23:29
в общем делаю так:
Код
...
procedure TForm1.SpeedButton5Click(Sender: TObject);
var h:THandle;
    hh:Dword;
begin
Timer1.Enabled:=true;
h:=CreateThread(nil,0,@CryptPack,nil,0,hh);
...
end;

Procedure CryptPack;
var i,j:word;
    pas:string;
begin
form1.ListBox1.Clear;
SetLength(TypFile,0);
RecTabAddFull(form1.DirectoryListBox1.Directory,TypFile);
i:=Length(TypFile);
for j:=0 to i-1 do
   begin
   form1.ListBox1.Items.Add(TypFile[j].rtFileName)
   end;
pas:=form1.Edit1.Text;
if not RecordFileC(form1.DirectoryListBox2.Directory+'\Test.chid', pas,TypFile) then
  MessageDlg('произошла ошибка. Файл не создан.',mtError,[mbOK],0)
  else
  MessageDlg('Файл создан.',mtInformation,[mbOK],0);
form1.edit1.text:='';                             // <- здесь ошибка : Canvas does not allow drawing и MessageDlg не показывается
form1.Timer1.Enabled:=false;
form1.ListBox2.Items.Add('Complit/')
end;
...


если не делать через поток, то всё работает нормально. и самое интересное что если сделать так:

Код
...
pas:=form1.Edit1.Text;
form1.edit1.text:='';
if not RecordFileC(form1.DirectoryListBox2.Directory+'\Test.chid', pas,TypFile) then
  MessageDlg('произошла ошибка. Файл не создан.',mtError,[mbOK],0)
  else
  MessageDlg('Файл создан.',mtInformation,[mbOK],0);
form1.Timer1.Enabled:=false;
...

то ошибка вылетает на form1.Timer1.Enabled:=false; При чём при пошаговой отладке эта ошибка не вылетает(?). Файл во всех случаях создаётся.

Объясните плз, в чём я не прав...

Автор: Albinos_x 29.12.2005, 00:05
я тут порылся в коде... MessageDlg не вылетает потому что на нём и вылетает ошибка... если эти строчки убрать то уже ошибка не вылетает...
может есть ещё способ как вывести из потока сообщение о завершении работы процедуры?

Автор: Snowy 29.12.2005, 00:09
MessageBox(0, 'Я всё', 'Поток', MB_OK);
Добавлено @ 00:14
Код

MessageBox(0, 'Файл не создан.', 'Ошиппка', MB_OK or MB_ICONERROR);
MessageBox(0, 'Файл создан.', 'Усё Ok!', MB_OK or MB_ICONINFORMATION);

Автор: Albinos_x 29.12.2005, 00:23
СПАСИБО! smile
Всё работает...
поясни пожалуйста, почему MessageDlg не хотел работать?

Автор: Snowy 29.12.2005, 00:34
Потому что MessageDlg принадлежит Application.
Поэтому тебе нельзя юзать user объекты основного потока.
А MessageBox - чистый WinAPI. Он никому не принадлежит.
Но работать с классами из вторичного потоко не рекомендуется -
будут накладки основного и вторичного потока.
Особенно, если таких потоков много.
Например form1.ListBox1.Items.Add(TypFile[j].rtFileName).
Если он одновременно будет вызван из двух потоков, то лажа получится.
Поэтому по всем правилам рекомендуется работать с визуальными компонентами только в синхронизации.

Автор: Albinos_x 29.12.2005, 00:43
ясно...

Цитата(Snowy @ 29.12.2005, 00:34)
Например form1.ListBox1.Items.Add(TypFile[j].rtFileName).
Если он одновременно будет вызван из двух потоков, то лажа получится.

это у меня пока тестовое приложение... а так я буду блокировать вызов ещё одного потока, пока этот не закончит работать...

еще раз СПАСИБО! smile

Автор: Демо 29.12.2005, 01:01
Цитата(Albinos_x @ 29.12.2005, 01:43)
а так я буду блокировать вызов ещё одного потока, пока этот не закончит работать...


Нельзя работать в дополнительном потоке с формами. Ни в каком виде.

Автор: Albinos_x 29.12.2005, 01:13
Цитата
Нельзя работать в дополнительном потоке с формами. Ни в каком виде.

у меня всё нормально работает... если не использовать поток, то мне придётся по всему коду ProgressMessages расставлять, что не есть хорошо...

Автор: Демо 29.12.2005, 09:50
Цитата(Albinos_x @ 29.12.2005, 02:13)
у меня всё нормально работает...


Ну хорошо... До поры работает.

Цитата(Albinos_x @ 29.12.2005, 02:13)
если не использовать поток, то мне придётся по всему коду ProgressMessages расставлять, что не есть хорошо..


Зачем?

Ты, скорее всего, логику спроектировал неправильно.
У тебя поток чем занимается?

Автор: Albinos_x 29.12.2005, 10:42
Цитата
У тебя поток чем занимается?

чтение(одного или нескольких)/запись(в один) файла(ов)
Добавлено @ 10:46
Цитата
Зачем?

если не проставлять (или не организовывать поток), то приложение будет "зависать" на время обработки файлов... это не очень хорошо смотрится... причём процесс обработки из-за этого тоже не отображается...

Автор: Демо 29.12.2005, 10:53
Цитата(Albinos_x @ 29.12.2005, 11:42)
если не проставлять (или не организовывать поток), то приложение будет "зависать" на время обработки файлов... это не очень хорошо смотрится... причём процесс обработки из-за этого тоже не отображается...


В принципе, логически правильно.

Для подобных задач существует 2 простых решения.
1. Поток работает, но процессом отображения хода работы доп. потока занимается основной поток.
Самое простое и логичное решение. Но не всегда приемлимо, если основной поток вообще не должен знать о
дополнительном. Синхронизация не вызывает проблем.
2. Поток работает, в нем же создается окно средствами Win32Api, в котором и отображается ход работы потока.
Решение хорошее, но несколько более трудоемкое. Синхронизация не требуется.

Автор: Albinos_x 29.12.2005, 11:09
Цитата
1. Поток работает, но процессом отображения хода работы доп. потока занимается основной поток.
Самое простое и логичное решение. Но не всегда приемлимо, если основной поток вообще не должен знать о
дополнительном. Синхронизация не вызывает проблем.
2. Поток работает, в нем же создается окно средствами Win32Api, в котором и отображается ход работы потока.
Решение хорошее, но несколько более трудоемкое. Синхронизация не требуется.

ну я писал, что это пока тестовое приложение... поэтому остановился на блокировке вызова второго потока... а когда буду делать не тестовое думаю всё таки остановиться на втором варианте....

Спавибо за совет.

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