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

Вниз

Как правильно удалить поток в различных ситуациях   Найти похожие ветки 

 
Пусик ©   (2006-06-01 14:25) [40]


> В этом случае произайдет закрытие метедоа...

-))


 
begin...end ©   (2006-06-01 14:27) [41]

> Пусик ©   (01.06.06 14:22) [37]

Это не перекрытие. А кто этот второй Free вызывать будет?


 
Kolan ©   (2006-06-01 14:27) [42]


> Ожидать завершения потока - метод WaitFor;

Так а если он повис, вдруг я ошибку сделал.. Тогда что при закрытии приложение повиснет? Это еще хуже..

Я вот просто жадержку втавил Sleep(10); и все завершилось...
Как такой вариант? Нормальный?


 
Kolan ©   (2006-06-01 14:30) [43]


> procedure TMyClass.Free;
> begin
>  ShowMessage("!");
>  inherited;
> end;


Попробуй что будет если объявить
var
 MyObj: TObject;
begin
 создать как
 MyObj := TMyClass.Create;
 и вызвать
 MyObj.Free;
end;


 
Пусик ©   (2006-06-01 14:34) [44]


> begin...end ©   (01.06.06 14:27) [41]
> > Пусик ©   (01.06.06 14:22) [37]
>
> Это не перекрытие. А кто этот второй Free вызывать будет?
>


Может быть, термин и неточный, но посмотрю, когда доберусь до компьютера с Delphi.
А вызываться Free вызывается, причем именно так, как от него и ожидается.


> Kolan ©   (01.06.06 14:30) [43]



> Попробуй что будет если объявить
> var
>  MyObj: TObject;
> begin
>  создать как
>  MyObj := TMyClass.Create;
>  и вызвать
>  MyObj.Free;
> end;


Я-то пробовала. Ты лучше сам попробуй;)


 
Пусик ©   (2006-06-01 14:36) [45]


> Kolan ©   (01.06.06 14:30) [43]
>
> > procedure TMyClass.Free;
> > begin
> >  ShowMessage("!");
> >  inherited;
> > end;
>
>
> Попробуй что будет если объявить
> var
>  MyObj: TObject;
> begin
>  создать как
>  MyObj := TMyClass.Create;
>  и вызвать
>  MyObj.Free;
> end;


Честно говоря, не поняла сначала, о чем этот код. Не поняла, для чего приведен пример и после того, как подумала над ним.


 
begin...end ©   (2006-06-01 14:38) [46]

> Пусик ©   (01.06.06 14:34) [44]

Когда доберётесь до компьютера, посмотрите код VCL, если не трудно -- там новые Free не добавляются, а вместо этого перекрывается виртуальный Destroy. Это типа пища для размышления такая.


 
Kolan ©   (2006-06-01 14:39) [47]

type
 TForm1 = class(TForm)
   BitBtn1: TBitBtn;
   procedure FormCreate(Sender: TObject);
   procedure BitBtn1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

 TMyClass = class
   procedure Free;
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin

end;

{ TMyClass }

procedure TMyClass.Free;
begin
 ShowMessage("!");
 inherited;
end;


procedure TForm1.BitBtn1Click(Sender: TObject);
var
 MyObj: TObject;
begin
 MyObj := TMyClass.Create;
 try
 finally
   MyObj.Free;
 end
end;

end.

Пожалуйте.

Компилятор кстати выделеной жирным вообще выбросил...за ненадобностью...


 
Kolan ©   (2006-06-01 14:39) [48]

А если пытаться перекрыть:
TMyClass = class
   procedure Free; override;
 end;

то,
[Error] Unit1.pas(21): Cannot override a static method
...


 
Пусик ©   (2006-06-01 14:43) [49]


> Компилятор кстати выделеной жирным вообще выбросил...за
> ненадобностью...


Ну да. Потому что обращаемся к MyObject как к TObject.
Почему бы не указать компилятору тип объекта явно?

procedure TForm1.BitBtn1Click(Sender: TObject);
var
MyObj: TMyClass;
begin
MyObj := TMyClass.Create;
try
finally
  MyObj.Free;
end
end;


 
Пусик ©   (2006-06-01 14:44) [50]


> begin...end ©   (01.06.06 14:38) [46]
> > Пусик ©   (01.06.06 14:34) [44]
>
> Когда доберётесь до компьютера, посмотрите код VCL, если
> не трудно -- там новые Free не добавляются, а вместо этого
> перекрывается виртуальный Destroy. Это типа пища для размышления
> такая.


Ну и что, что в исходниках VCL не перекрывается этот метод?
Кто-то запрещает это делать?
Посмотреть мне нетрудно, тем более что делаю это постоянно.

А пищу для размышлений обычно более конкретную подкидывают, а не общие фразы. Это так... тоже тема для размышлений.


 
Kolan ©   (2006-06-01 14:51) [51]


> Пусик ©   (01.06.06 14:43) [49]

Вот странно по потокам советуете а основ не знаете :)

> Почему бы не указать компилятору тип объекта явно?

В этом то и смысл перекрытия(полиморфизма).

Классический пример:
Допустим у меня есть 1 предок - фигура:
TShape = class
 procedure Draw; virtual;
end;


И множество потомков(Для примера пусть 2):

TCircle = class(TShape)
 procedure Draw; override;
end;


TSquare = class(TShape)
 procedure Draw; override;
end;


В каждой из перекрытых процедур Draw я напишу конуретную реализацию рисования фигуры.

ТЕперь можно воспользоваться полиморфизмом:

var
 //Объявляю объект - типа предка TShape
 MyObj: TShape;
begin
 // А создаю его как потомка
 MyObj := TCircle.Create;
 // Рисую
 MyObj.Draw;
 // При вызове Draw будет вызвана процедура не предка (TShape), а его потомка(TCircle). Эта произойдет тк процедура драв перекрыта в VMT.  

//Удалю его
 MyObj.Free;
 
 //
 MyObj := TSquare.Create;
 MyObj.Draw;
 // Теперь нарисуется квадрат :)
 MyObj.Free;
end;


 
Kolan ©   (2006-06-01 14:53) [52]


> Ну и что, что в исходниках VCL не перекрывается этот метод?
>
> Кто-то запрещает это делать?


Просто не виртуальный метод НЕльзя перекрыть:
Посмотрите вот это:
http://ru.wikipedia.org/wiki/%D0%92%D0%B8%D1%80%D1%82%D1%83%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D1%8F


 
Kolan ©   (2006-06-01 14:53) [53]

Пример на Delphi написан лично мной...


 
Пусик ©   (2006-06-01 15:52) [54]


> Kolan ©   (01.06.06 14:51) [51]
>
>
> > Пусик ©   (01.06.06 14:43) [49]
>
> Вот странно по потокам советуете а основ не знаете :)
>
> > Почему бы не указать компилятору тип объекта явно?
>
> В этом то и смысл перекрытия(полиморфизма).


Да не нужен здесь полиморфизм.
И другие примеры не нужны.

Я ж сказала, неправлильный термин исползовала.
В моем примере метод не перекрывается, а замещается.
И лишь в конце вызывается метод предка.


 
Kolan ©   (2006-06-01 16:01) [55]

Закрывать метод нодо с осторожностью... Не даром компилятор предупреждеие выдает.
В любом случае всех благодарю за ответы. Остался один вопрос:

>
> Я вот просто жадержку втавил Sleep(10); и все завершилось.
> ..
> Как такой вариант? Нормальный?
>


 
Сергей М. ©   (2006-06-01 16:17) [56]


> б). Поток чего-то ждет. Например ф-цией WaitForSingleObject.
>  И его надо удалить


Поток может ждать и [Msg]WaitForMultipleObjects() - функциональность та же, но поток приобретет возможность оперативно реагировать на команды "немедля закругляться по хозяйству"

Можно приспособить и WaitForSingleObject(), опубликовав хэндл объекта синхронизации, сигнала которого ждет поток.

Т.е. просторы для фантазии здесь не ограничены.

Единственное что нельзя сделать - это, например, прервать блок.вызовы синхронных ф-ций пайп-транспорта, если система не Longhorn и не Vista.


 
Пусик ©   (2006-06-01 16:20) [57]


> Как такой вариант? Нормальный?


Не совсем. Поток может не закончиться и через 10, и через 1000мсек.

Лучше так:

var
 RC: DWORD;
begin
...
RC := WaitForSingleObject(MyThread.Handle,1000);
if RC=WAIT_TIMEOUT then TerminateThread(...);
и т. д.


 
Сергей М. ©   (2006-06-01 16:22) [58]


> Пусик ©   (01.06.06 16:20) [57]


Зачем же через секунду сразу убивать поток ?
А вдруг ему требуется еще чуть-чуть до нормального завершения ?


 
Пусик ©   (2006-06-01 16:26) [59]


> А вдруг ему требуется еще чуть-чуть до нормального завершения
> ?
>


Ну так здесь уже дело хозяйское - какое время ожидать завершения. Я только пример привела.



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

Текущий архив: 2006.07.16;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.036 c
2-1150997721
аматор
2006-06-22 21:35
2006.07.16
свойство parent


2-1151559279
lobach
2006-06-29 09:34
2006.07.16
Расположение


15-1150560517
TUser
2006-06-17 20:08
2006.07.16
Рассылочка пришла


15-1150533422
grisme
2006-06-17 12:37
2006.07.16
Вопрос по WinSock


15-1150345618
Александр Иванов
2006-06-15 08:26
2006.07.16
Алгоритмы поиска маршрута в графе