Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: Ctrl  назад   1 2 3 4 5 6 [7] 8 9 10 11 .. 19   вперед  Ctrl
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25711
Док
Ты можешь этот тынц сам увидеть, если Лазарь откроешь Вечерком могу выложить тестовый проект (ноут дома).

Жду... Хоть пойму, при чем здесь приватные поля основного потока. :)
30 июл 14, 09:48    [16374939]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Док
Member

Откуда: Казань
Сообщений: 6287
wadman,
+

"— Слушай, я русский язык не хорошо знаю… Он пошёл туалет, а Валико постучил дверь и сказал — что тоже… хочет… Такие вопросы задаёте, что неудобно отвечать… даже…"

Вечером, все вечером ...
30 июл 14, 10:08    [16375030]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Док
Member

Откуда: Казань
Сообщений: 6287
Ну вот например:
+ интерфейс
  { TMyThread }

  TMyThread = class(TThread)
  protected
    procedure Execute; override;
  end;

  { TFrmMain }

  TFrmMain = class(TForm)
    BtnRun: TButton;
    Label1: TLabel;
    procedure BtnRunClick(Sender: TObject);
  private
    { private declarations }
    FStrMgs: String;
    FMyThread: TMyThread;
  public
    { public declarations }
  end;
+ implementation
{ TMyThread }

procedure TMyThread.Execute;
var
  i: Integer;
begin
  i:= 0;
while i < 200 do
  begin
    Inc(i);
    FrmMain.FStrMgs:= Format('I = %d',[i]); //а дельфи так может?
    Sleep(50);
  end;

Terminate;
end;

{ TFrmMain }

procedure TFrmMain.BtnRunClick(Sender: TObject);
begin
  FMyThread:= TMyThread.Create(False);
  FMyThread.Priority:= tpLower;
  FMyThread.FreeOnTerminate:= True;

  while not FMyThread.Finished do
    begin
      Label1.Caption:= FStrMgs;
      Application.ProcessMessages;
      BtnRun.Enabled:= FMyThread.Finished;
    end;
end; 
+ картинко
Картинка с другого сайта.

Под основным потоком я подразумевал поток, в котором Гуй отрисовывается

К сообщению приложен файл (test.zip - 2Kb) cкачать
30 июл 14, 15:13    [16377472]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25711
Док
    FrmMain.FStrMgs:= Format('I = %d',[i]); //а дельфи так может?

С трудом себе представляю, зачем это нужно. Ведь оно само по себе не о чем не говорит главному потоку, который в это время выполняет мягко говоря такой г-код, чтобы самому догадаться об изменениях переменной:
Док
while not FMyThread.Finished do
    begin
      Label1.Caption:= FStrMgs;
      Application.ProcessMessages;
      BtnRun.Enabled:= FMyThread.Finished;
    end;

Да и по идее этот код должен загрузить процессор.

Потому все таки правильнее и проще передать новое значение переменной вместе с сообщением. Или я не до конца разглядел твою мысль?
30 июл 14, 15:22    [16377530]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Док
Member

Откуда: Казань
Сообщений: 6287
wadman
который в это время выполняет мягко говоря такой г-код, чтобы самому догадаться об изменениях переменной

честно говоря, не понял - основной поток не в силах уследить, что делается с его переменными?

зы. Я не спорю, я просто интересуюсь, ибо гуманитарий ;)
30 июл 14, 15:51    [16377747]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25711
Док
основной поток не в силах уследить, что делается с его переменными?

Ты привел один из способов самостоятельного отслеживания изменений. Сам понимаешь, вариант совсем не вариант. Все таки сообщения, содержащие новые данные как-то более надежный и простой механизм.

Грубо говоря я не увидел применения твоему способу.
30 июл 14, 16:18    [16377930]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Док
Member

Откуда: Казань
Сообщений: 6287
wadman
Ты привел один из способов самостоятельного отслеживания изменений.

Ты имеешь ввиду ProcessMessages?
30 июл 14, 16:32    [16378004]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25711
Док
wadman
Ты привел один из способов самостоятельного отслеживания изменений.

Ты имеешь ввиду ProcessMessages?

Именно.
30 июл 14, 16:43    [16378078]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Док
Member

Откуда: Казань
Сообщений: 6287
wadman,

ну, у меня тогда появился повод переписать код на событийную модель
30 июл 14, 22:12    [16379434]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25711
Док
ну, у меня тогда появился повод переписать код на событийную модель

А было так, как ты показал?
31 июл 14, 09:03    [16379999]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Док
Member

Откуда: Казань
Сообщений: 6287
wadman,

поскольку в тонкости диспетчеризации сообщений я стал вникать только в последнее время, то в Лазаре (а ЕМНИП, Дельфя описанных мною выше вольностей не позволяла) в тестовых проектах для разнообразия я где-то написал так, а где-то по другому.

Теперь, конечно же, придется делать по фен-шую :)

зы. Лазарь вообще, отдельная песТня. Я тут виндовые проекты стал портировать в никсы - много интересного познал
1 авг 14, 08:35    [16385306]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Максим Улитин
Member

Откуда: Москва
Сообщений: 87
Достаточно часто (но не всегда) в одном и том же месте появляется ошибка.
Access violation at address .... in module 'MyExe.exe'. Read of address 0000000F.

WThread.TWThread.PostToThreadMessage (Line 393, "WThread.pas") - по EurekaLog

версия от 28.07.2014
result := (not Suspended)and(PostThreadMessage(ThreadID, Msg, wParam, lParam));

Не знаю как лечить. Может быть поможете?
Раньше использовали предыдущие версии и все нормально работало.
20 янв 15, 14:46    [17143142]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25711
Максим Улитин
WThread.TWThread.PostToThreadMessage (Line 393, "WThread.pas") - по EurekaLog

А остальное, что было до этого? И что отправляется?
20 янв 15, 14:51    [17143165]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Максим Улитин
Member

Откуда: Москва
Сообщений: 87
wadman,

сейчас отправлю в личку.

А так, вкратце там выводится форма с часиками (что типа что-то выполняется и ждите). форма нарисована на winapi. с помощью вашего класса все данные на этой форме обновляются.
21 янв 15, 10:26    [17146821]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Максим Улитин
Member

Откуда: Москва
Сообщений: 87
wadman,

что-то лички тут не нашел, ладно, тогда так отправлю

К сообщению приложен файл (fmStatus.7z - 10Kb) cкачать
21 янв 15, 10:28    [17146838]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25711
Максим Улитин, то, что я там увидел - это тотальное непонимание как работать с потоками и памятью...

Например: Под параметры память выделяется, а под текст - нет. См. функции NewString, FreeString.
Procedure MyThreadMessageDlgWarnOk(ThreadParams: PThreadParams;
  Const MessageText: String);
Begin
  If ThreadParams = Nil Then
    Exit;
  ThreadParams^.MessageType := mtWarning;
  ThreadParams^.MessageText := MessageText;     

Это зачем дергается в другом потоке?
Procedure TTimerThread.Execute;
Begin
  Inherited;

  While Not Terminated Do
  Begin
    Sleep(400);
    If Not Stop Then
      Synchronize(UpdateForm);
  End;
End;

Procedure TTimerThread.UpdateForm;
Var
  frmStatus: TfrmStatus;
Begin
  If QuickSameText(Params.ProgressBar.Properties.Text, ExcelCreate) Then
  Begin
    Application.ProcessMessages;
    Exit;
  End;   

Ниже еще интереснее: зачем sleep?
  FWThread.FStart := Now;
  If Not ThreadParams.NoShowForm Then
  Begin
    Application.ProcessMessages;
    Sleep(250);
    FWThread.PostToThreadMessage(WM_SHOW1, 0, 0);
    Sleep(250);
    Application.ProcessMessages;
  End;  


На сколько я понял - это тяжелое наследие какого-то участка кода, который когда-то работал в одном потоке и теперь стоит задача разнести на разные?

Чтобы найти место, где и из-за чего возникает ошибка вынеси TWindowThread в отдельный модуль и протестируй его на пустом проекте.
21 янв 15, 11:09    [17147188]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25711
Взглянул более внимательно... Это стоит переписать с нуля. Совсем.
Вынести экспорт в другой поток будет проще.
21 янв 15, 11:40    [17147456]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Максим Улитин
Member

Откуда: Москва
Сообщений: 87
wadman,

Ну там все намного проще. раньше все это было написано как класс, в котором запускается отдельной процесс с какой-то логикой. То есть был основной поток с программой, из основного потока создавался поток с нужной процедурой и еще один поток для отрисовки окна.
все работало нормально, без каких либо ошибок и все было хорошо. Но пришлось все переписывать, так как если в этом отдельном потоке создавался fastreport с поддержкой мультизадачности (EnableThreadSafe = False), то по полной начинало все глючить.
И из-за этого было быстренько все переписано и теперь поток не создается с нужной процедурой, а выполняется в основном потоке. А для отрисовки окна используется Ваш класс. Да, переписано все через ж.., но к сожалению что есть, то и есть. Вначале писал я (с кучей поток), переписывал не я, а человек, который уже был уволен за кучу своих ошибок.
N-ая часть этого кода из приложенного файла не используется уже совсем, валяется как мусор или пережиток былого. А почистить времени нет.

> На сколько я понял - это тяжелое наследие какого-то участка кода, который когда-то работал в одном потоке и теперь стоит задача разнести на разные?
Наоборот, был когда то перевод с кучи потоков на один поток (ну +1 на форму с "часиками")

sleep нужен для того, чтобы сообщение нормально отправилось. На некоторых машинах форма просто не успевала создаться (сообщение о показе формы приходило чуть позднее)

> Например: Под параметры память выделяется, а под текст - нет. См. функции NewString, FreeString.
раньше так все и было, сейчас это не нужно

Просто опять же, раньше на какой-то другой версии Вашего класса ошибка не возникала, сейчас возникает. Вот стало интересно почему, отсюда и спросил

P.S.: А так, по существу, как то никогда не было проблем как с потоками, так и с дин памятью, так и с тем, как с ней работать
21 янв 15, 12:57    [17148062]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25711
Максим Улитин
Просто опять же, раньше на какой-то другой версии Вашего класса ошибка не возникала, сейчас возникает. Вот стало интересно почему, отсюда и спросил

Раньше видимо и код экспорта был иным. В том коде, который приведен ошибки такой быть не может. По меньшей мере при работе именно с wthread (предлагаю протестировать на пустом приложении). А проблемы с памятью имеются и я их показал. Потому и просил стек вызова показать.
Скорее всего поток к тому времени не создан, либо убит (то есть равен nil) и обращение к ThreadID вызывает ошибку.
wadman
А остальное, что было до этого?

Максим Улитин
Но пришлось все переписывать, так как если в этом отдельном потоке создавался fastreport с поддержкой мультизадачности (EnableThreadSafe = False), то по полной начинало все глючить.

Фастрепорт глючит именно из-за тех-же ошибок, что я и показал. Они тоже любят баловаться Application.ProcessMessages не анализируя EnableThreadSafe. :) Я и его наставил на путь истинный 2 года назад и с тех пор не обновляю. Теперь он работает в потоках.
Максим Улитин
sleep нужен для того, чтобы сообщение нормально отправилось.

Формы можно создавать заранее скрытыми.
21 янв 15, 13:11    [17148159]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Максим Улитин
Member

Откуда: Москва
Сообщений: 87
wadman,

код экспорта был таким же с точностью до байта, как и в тех версиях Вашего класса. Кстати еще раз, это не экспорт, а выполнение любых процедур, когда заранее точно не известно выполнится ли эта процедура быстро или нет.
На тему Procedure TTimerThread.UpdateForm; - он не используется совсем у меня. Как уже сказал, остались части, надо вычистить.

На тему слипа. там идет основной поток программы, а раз так, то могу делать в основном потоке что хочу. Разве нет?

На тему ThreadParams^.MessageText := MessageText;
ThreadParams - это рекорд, под который выделена память с помощью new. По моему я уже выделил память, в том числе и под строку. А работаю исключительно с указателем на этот рекорд и эту строку. Разве нужно еще раз выделять память под строку уже в выделенной памяти под весь рекорд?

> А проблемы с памятью имеются и я их показал.
вроде проблем этих нет. могу конечно просмотреть в дебаге в отдельном приложении. Только боюсь под это уйдет уйма времени, так как ошибка на реальных проектах возникает очень часто раз из тысячи, а бывает сразу.

> Скорее всего поток к тому времени не создан, либо убит (то есть равен nil) и обращение к ThreadID вызывает ошибку.
вполне возможно, надо попробовать поставить проверку
21 янв 15, 16:56    [17150024]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25711
Максим Улитин
ThreadParams - это рекорд, под который выделена память с помощью new.

Вот тебе и понимание работы с памятью и потоками... String по умолчанию уже давно лишь ссылка на участок памяти с символами.
21 янв 15, 17:01    [17150080]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Максим Улитин
Member

Откуда: Москва
Сообщений: 87
wadman,

> String по умолчанию уже давно лишь ссылка на участок памяти с символами
конечно я это знаю

> Вот тебе и понимание работы с памятью и потоками
оке, тогда объясни что не так? и почему огромное количество времени (с 2006 по 2013 год) предыдущий вариант этого класса (моего класса формы с часами) работал БЕЗ ЕДИНОЙ ПРОБЛЕМЫ?
проблема с EnableThreadSafe = false не в счет, тут уже прикол самого фастрепорта, как Вы сами написали.
21 янв 15, 17:14    [17150199]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 25711
Максим Улитин
оке, тогда объясни что не так? и почему огромное количество времени (с 2006 по 2013 год) предыдущий вариант этого класса (моего класса формы с часами) работал БЕЗ ЕДИНОЙ ПРОБЛЕМЫ?

Я не знаю как еще объяснить. Что именно тут не понятно?
wadman
String по умолчанию уже давно лишь ссылка на участок памяти с символами.

Везение это не положительная оценка навыков программирования, если что.
21 янв 15, 17:19    [17150253]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Dimonka
Member

Откуда:
Сообщений: 1179
wadman
Максим Улитин
ThreadParams - это рекорд, под который выделена память с помощью new.

Вот тебе и понимание работы с памятью и потоками... String по умолчанию уже давно лишь ссылка на участок памяти с символами.

Если не считать ещё уличной магии массивов, которая подчищает строки при выходе из процедуры.
21 янв 15, 17:23    [17150280]     Ответить | Цитировать Сообщить модератору
 Re: Шаблон класса для работы с потоком (WThread, Thread)  [new]
Максим Улитин
Member

Откуда: Москва
Сообщений: 87
wadman,

оке, тогда помоги плиз, если конечно не затрудняю.
нужно запускать процедуру в том же потоке, что и основная программа, но при этом создавалась форма, в котором был label с каким-то там сообщением, которое можно менять в любой момент времени, progressbar, который так же можно менять, иконка для красивости и label с временем, который показывало сколько времени прошло с момента запуска данной процедуры. Но при этом в тексте самих этих процедур на запуск ничего переделывать было бы не надо.
21 янв 15, 17:25    [17150304]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 2 3 4 5 6 [7] 8 9 10 11 .. 19   вперед  Ctrl
Все форумы / Delphi Ответить