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

Вниз

Онять несчастный TThread   Найти похожие ветки 

 
Death   (2002-01-25 08:34) [0]

Вопрос на засыпку:
на форме находиться label & Buton.
при нажатии на кнопку выполняется такая процедурка:


procedure TForm1.Button1Click(Sender: TObject);
begin
if not Running_Count then
begin
Button1.Caption:="Stop";
th:=TCountThread.Create;
end
else
begin
Button1.Caption:="Start";
// здесь я пробовал разные варианты уничтожения нити... этот оказался самым долгоневылетающим :) а вообще-то хотелось бы использовать простой Терминайт или Дестрой...
th.Terminat:=true;
if WaitForSingleObject(th.Handle,3000)<>0 then
showmessage("Допустим таймаут! (конечно если значение ~258 - не помню точно уже :)");
end;
end;


триада оперделена сразу после формы:

var
Form1: TForm1;
th : TCountThread;


тип триады определён в отдельном модуле, который приведу полностью, чтоб небыло непоняток:


type
TCountThread = class(TThread)
private
FCount: Int64;
FTerminat: Boolean;
procedure ViewCount;
procedure SetCount(const Value: Int64);
procedure SetTerminat(const Value: Boolean);
protected
procedure Execute; override;
procedure DoCount(const Path: string);
public
property Count : Int64 read FCount write SetCount;
property Terminat : Boolean read FTerminat write SetTerminat;
constructor Create;
destructor Destroy; override;
end;

var Running_Count : Boolean = False;

implementation
uses unit1;
{ TCountThread }

constructor TCountThread.Create;
begin
inherited Create(False);
FreeOnTerminate:=True;
Running_Count:=True;
FCount:=0;
FTerminat:=False;
end;

destructor TCountThread.Destroy;
begin
inherited Destroy;
Running_Count:=False;
form1.Label1.Caption:=inttostr(FCount);
end;

procedure TCountThread.DoCount(const Path: string);
var
CR, cr1: TSearchRec;

function IsDirNotation(ADirName: String): Boolean;
begin Result := (ADirName = ".") or (ADirName = ".."); end;

begin
if FindFirst(Path + "*.*", faAnyFile, cR1) = 0 then
try
cr:=cr1;
repeat
if not IsDirNotation(cR.Name) then
begin
if ((cR.Attr and faDirectory) = faDirectory) then
begin DoCount(Path + cR.Name + "\"); Continue;end;
inc(FCount);
Synchronize(ViewCount);
end;
until (FindNext(cR) <> 0) or FTerminat;
finally
SysUtils.FindClose(cR1);
end;
end;

procedure TCountThread.Execute;
begin
DoCount("C:\");
DoCount("D:\");
end;

procedure TCountThread.SetCount(const Value: Int64);
begin
FCount := Value;
end;

procedure TCountThread.SetTerminat(const Value: Boolean);
begin
FTerminat := Value;
end;

procedure TCountThread.ViewCount;
begin
form1.Label1.Caption:=inttostr(FCount);
end;


А теперь если сделать такую весчь:
1. быстро нажимать на бутон (Enter-ом), т.е. очень частое и быстрое создание и уничтожение триады - эксепшена может и не быть.
2. нажать и держать Энтер... :(( вылет обеспечен...

ВОПРОС: как сделать, чтоб вылета не было?
обработку эксепшенов не предлагать. :)


 
panov   (2002-01-25 09:05) [1]

procedure TForm1.Button1Click(Sender: TObject);
begin
if not Running_Count then
begin
Button1.Caption:="Stop";
th:=TCountThread.Create;
end
else
begin
th.Terminate;
end;
end;

constructor TCountThread.Create;
begin
// inherited Create(False);
inherited Create(True);
FreeOnTerminate:=True;
Running_Count:=True;
FCount:=0;
FTerminat:=False;
Resume;
end;

procedure TCountThread.DoCount(const Path: string);
var
CR, cr1: TSearchRec;

function IsDirNotation(ADirName: String): Boolean;
begin Result := (ADirName = ".") or (ADirName = ".."); end;

begin
// if FindFirst(Path + "*.*", faAnyFile, cR1) = 0 then
if (FindFirst(Path + "*.*", faAnyFile, cR1) = 0) and
(not Terminated) then

try
cr:=cr1;
repeat
if not IsDirNotation(cR.Name) then
begin
if ((cR.Attr and faDirectory) = faDirectory) then
begin DoCount(Path + cR.Name + "\"); Continue;end;
inc(FCount);
Synchronize(ViewCount);
end;
// until (FindNext(cR) <> 0) or FTerminat;
until (FindNext(cR) <> 0) or Terminated;
finally
SysUtils.FindClose(cR1);
end;
end;

destructor TCountThread.Destroy;
begin
Running_Count:=False;
// form1.Label1.Caption:=inttostr(FCount);
inherited Destroy;
end;


 
Death   (2002-01-25 09:28) [2]

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

у меня раньше так и было... небыло только одной строчки:
if (FindFirst(Path + "*.*", faAnyFile, cR1) = 0) and
(not Terminated) then


и ещё интересует: обязательно ли криэйтить триаду в режиме паузы? я его толькошо заблокировал - всё работает тоже нормально.



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

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

Наверх




Память: 0.46 MB
Время: 0.009 c
1-18910
Dtr
2002-01-24 10:01
2002.02.07
PopUpMenu


1-18848
Eraser
2002-01-21 15:38
2002.02.07
Погибаю в пучине потоков (уже давно)


3-18733
ADy
2002-01-10 22:01
2002.02.07
SQL, Interbase


3-18700
dymka
2002-01-09 14:01
2002.02.07
TQuery в Runtime


6-18927
alex16
2001-11-15 07:40
2002.02.07
Ошибка





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский