Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2016.07.24;
Скачать: [xml.tar.bz2];

Вниз

Xe7 и Thread   Найти похожие ветки 

 
AntonArm   (2014-10-10 18:18) [0]

подскажите, создаю пустой поток с FreeOnTerminate := true;
MyThread:= TMyThread.Create(false);

поток отработал.

проверяю Assignet(MyThread)  даёт True.
добавил публичную процедурку ShowData:

procedure TMyThread.DoWork;
begin
  ShowMessage("я живой!");
end;

procedure TMyThread.ShowData;
begin
  Synchronize(DoWork);
end;

после отработки потока вызываю  myThread.ShowData - работает.
проверил на Delphi2007 - ошибка, поток видать реально уничтожается после завершения.

не могли бы проверить, может я что-то путаю?


 
MBo ©   (2014-10-10 20:16) [1]

>Assignet(MyThread)  даёт True.
объект освобождается, но переменная не обнуляется, так что проверка Assigned бесполезна.
Если нужно знать, когда поток завершился, то для извещения об этом есть событие OnTerminate.


 
AntonArm   (2014-10-10 21:13) [2]

MBo ©, да, да - я это понял.
мне просто не понятно почему после отработки потока,
повторный вызов MyThread.ShowData  отрабатывается.


 
Игорь Шевченко ©   (2014-10-10 21:28) [3]


> повторный вызов MyThread.ShowData  отрабатывается.


Потому что это обычная процедура и выполняется она в контексте того потока, откуда ее вызвали, в данном случае - основного


 
Rouse_ ©   (2014-10-10 21:44) [4]


> не могли бы проверить, может я что-то путаю?

Ничего ты не путаешь - просто такой вызов невалиден изначально.
А уж в контексте какой нити выполнятется указаный тобой вызов - вообще велосипедно, ибо ты работаешь с уже разрушеным объектом.


 
Rouse_ ©   (2014-10-10 21:50) [5]

Советую подключить FastMM (в виде сторонней библиотеки) она тебе сразу покажет что ты делаешь неправильно, особливо даст понятия по обращению к обьекту, разрушенному в сторонней нити (потоке).


 
AntonArm   (2014-10-10 21:51) [6]

>> ибо ты работаешь с уже разрушеным объектом.

вот вот!
MyThread:= TMyThread.Create(false);
нить отрабатывает, вызывается OnTerminate.

после чего вызываю MyThread.ShowData
в Delphi2007 вываливается
в Xe7 - отрабатывет ShowMessage("я живой!");


 
AntonArm   (2014-10-10 21:55) [7]

>> Советую подключить FastMM

попробывал в цикле 1000 раз создавать поток - память не течет.
но MyThread.ShowData отрабатывает после окончания работы потока.
у кого XE6 или 7  проверьте пожалуйста..


 
AntonArm   (2014-10-10 21:59) [8]

добавил в нить глобальную строковую переменную.
в execute только присваиваю ей значение.
в procedure TMyThread.DoWork;
begin
 ShowMessage(myStr);
end;

после отработки потока, вызываю MyThread.ShowData
ShowMessage отрабатывается, но выводится пустая строка.

вообще запутался что-то...


 
AntonArm   (2014-10-10 22:25) [9]

что бы было понятнее вот простой код:

  TMyThread = class(TThread)
  private
    myStr: String;

  protected
    procedure   DoWork;
    procedure   Execute;  override;
  public
    procedure ShowData;
  end;

...

procedure TMyThread.Execute;
begin
 myStr:= timeToStr(time);
 ShowData;
end;

procedure TMyThread.DoWork;
begin
  ShowMessage(myStr);
end;

procedure TMyThread.ShowData;
begin
  Synchronize(DoWork);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 MyThread:= TMyThread.Create(false);
 MyThread.FreeOnTerminate:= true;
 MyThread.Resume;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 MyThread.ShowData;
end;


меня смущает что отрабатывается MyThread.ShowData по второй кнопке на XE6 и 7 пустым сообщением.
в Delphi2007 получаю как и ожидаю access

как отрабатывается в Xe7 FreeOnTerminate не могу понять..


 
Игорь Шевченко ©   (2014-10-10 22:49) [10]


> А уж в контексте какой нити выполнятется указаный тобой
> вызов - вообще велосипедно, ибо ты работаешь с уже разрушеным
> объектом.


Точно ?


 
AntonArm   (2014-10-10 22:52) [11]

Игорь Шевченко ©,
>> Потому что это обычная процедура и выполняется она в контексте того потока, откуда ее вызвали

почему тогда в Delphi2007 эта обычная процедура не отрабатывается а в access вываливается?


 
Rouse_ ©   (2014-10-10 23:02) [12]

Точно, что именно? Что мы работаем с разрушеным обьектом или что так писать нельзя? :)


 
Rouse_ ©   (2014-10-10 23:05) [13]

С учетом [9] думаю смысл диспута исчерпан :)


 
AntonArm   (2014-10-10 23:16) [14]

Rouse_ ©,
простите, а что там такого увидели в [9] ?

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


 
AntonArm   (2014-10-10 23:20) [15]

в Xe7 и такой код работает:

  TMyObject = class(TObject)
  public
    procedure ShowData;
  end;

procedure TMyObject.ShowData;
begin
 ShowMessage(timeToStr(time));
end;

..

 MyObject:= TMyObject.Create;
 MyObject.ShowData;
 MyObject.Free;
 MyObject.ShowData; // работает!


ну не должно же ведь?!


 
Rouse_ ©   (2014-10-10 23:28) [16]

Оно не работает в обоих случаях, но в одном из них тебе просто повезло.


 
Rouse_ ©   (2014-10-10 23:32) [17]

Чтоб было более понятно, вынеси вызов ShowData чуть ниже по коду, и перед ним еще поработай с памятью, да хотяб еще раз создай десяток левых объектов


 
Rouse_ ©   (2014-10-10 23:38) [18]

Зы: дурной прмер сказал, самое простое, задекларируй данную прцедуру виртуальной, а там сам увидишь


 
AntonArm   (2014-10-10 23:48) [19]

Rouse_ ©, мне мысль ваша понятна..
я кстати так и пробывал: выделял большой кусок памяти, очищал обнулением..
вероятно мне не удалось затереть эту память.


 
AntonArm   (2014-10-10 23:57) [20]

>> задекларируй данную прцедуру виртуальной, а там сам увидишь

ничего не увидел - то же самое.. всё отрабатывает..


 
Германн ©   (2014-10-11 00:03) [21]


> ничего не увидел - то же самое.. всё отрабатывает..

Так карты сегодня легли Тройка, семерка, туз. Завтра будет тройка, семерка, дама. Можешь мне верить - я это знаю точно. :)


 
Rouse_ ©   (2014-10-11 00:05) [22]

Ну чтоб еще и с vmt повезло :) Везунчик, тогда бронебойный вариант, обьяви еще и переменную внутри класса, а внутри виртуального метода отображай ее значение


 
AntonArm   (2014-10-11 00:08) [23]

спасибо всем большое.
я даже рад, что здесь ступил.


 
Rouse_ ©   (2014-10-11 00:20) [24]

Бывает, обращайся ;)


 
Германн ©   (2014-10-11 01:46) [25]


> Rouse_ ©   (11.10.14 00:05) [22]
>
> Ну чтоб еще и с vmt повезло :) Везунчик, тогда бронебойный
> вариант, обьяви еще и переменную внутри класса, а внутри
> виртуального метода отображай ее значение

Может я что не понимаю. Почему "бронебойный" сей вариант?
И при чём тут особо vmt?


 
Object   (2014-10-11 16:32) [26]

> AntonArm   (10.10.14 23:16) [14]
> почему отрабатывает процедура, разрушенного объекта..


Потому что ShowData не обращается к полям этого объекта.

Объект уничтожен - это значит, что обращение к нему самому и к его полям стало невалидным (хотя, как тут уже говорилось, какое то время такое  обращение может давать и верные результаты, но валидным от этого не становится).

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


 
DVM ©   (2014-10-12 20:19) [27]


> почему отрабатывает процедура, разрушенного объекта..

Зачем вообще обращать к разрушенным объектам? Ты что не знаешь какие у тебя живые какие нет? Зачем тогда вообще стал использовать FreeOnTerminate? Постоянно вижу неправильно применение этого флага, которое ничего кроме глюков не привносит в программу. Ну хоть бы завел что-ли какой список потоков и по факту уничтожения удалял потоки оттуда. Тогда будешь точно знать, кто у тебя жив, а кто мертв. Или не используй FreeOnTerminate. Лично я вообще не одобряю данный флаг. Потоки это такая вещь, которую лучше не создавать и не уничтожать без надобности. Лучше держать всегда пул рабочих потоков, которые должны оперировать заданиями - нет заданий, спим, есть задания - работаем. И никакой магии с разрушением.


 
Германн ©   (2014-10-13 02:07) [28]


> Потоки это такая вещь, которую лучше не создавать ...
> без надобности.

Вот с этим я абсолютно согласен! Добавил бы ещё и без понимания как это всё работает.


 
Дмитрий Белькевич ©   (2014-10-22 01:24) [29]

>Assignet(MyThread)  даёт True.

местами делаю так:


procedure TDataModule3.OnBackupTerminate(Sender: TObject);
begin
FDBBackupThread := nil;
end;


 
Дмитрий Белькевич ©   (2014-10-22 01:26) [30]

>Лично я вообще не одобряю данный флаг

нормально. если уметь готовить. с потоками вообще нужно уметь готовить. если умеешь - нормально. если не умеешь - то и без FreeOnTerminate глюков не оберешься.



Страницы: 1 вся ветка

Форум: "Начинающим";
Текущий архив: 2016.07.24;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.005 c
3-1307684147
Pavor
2011-06-10 09:35
2016.07.24
BDE: Too many passwords


15-1444838876
aka
2015-10-14 19:07
2016.07.24
Топологическая сортировка


4-1277230542
Отшельник
2010-06-22 22:15
2016.07.24
Изменить значение в памяти чужой программы которое берется из INI


6-1281178432
syserg
2010-08-07 14:53
2016.07.24
Защита участка кода HTML


15-1442261724
Pavia
2015-09-14 23:15
2016.07.24
Определения.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский