Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2016.07.24;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




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


15-1441149908
Юрий Зотов
2015-09-02 02:25
2016.07.24
Наиважнейшая проблема...


15-1447345068
aka
2015-11-12 19:17
2016.07.24
Логический симулятор


15-1444562106
pavelnk
2015-10-11 14:15
2016.07.24
Подскажите компонент


15-1447172846
aka
2015-11-10 19:27
2016.07.24
Wifi router