![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Завершение работы потока [D7, XP]
v_a_belousov © (2010-12-05 17:23:00)Здравствуйте! Понимаю что вопрос заезженный, но столкнулся с проблемой завершения работы потока...
Есть поток, который после выполнения должен сам себя уничтожить
FreeOnTerminate := true
В самом потоке есть цикл
while Play do
begin
//тело потока в котором есть ещё один цикл
...
while pause do
begin
if not Play then exit;
Application.ProcessMessages;
end;
...
end;
Поток должен уничтожаться при выходе из программы. Перед вызом Close главной формы пишу Play := false; что должно привести к завершению потока, но почему то после того как главная форма закрывается начинаются ужасные тормоза и лаги, несмотря на то что процессор не загружен абсолютно и память тоже свободна. Ошибок ни каких при этом не возникает. Иногда все закрывается нормально и никаких лагов и тормозов. В чем проблема не понимаю... Пробовал вручную завершать Terminate; Free; результат тот же... Подскажите пожалуйста с чем это может быть связано.
v_a_belousov (2010-12-05 23:33:00) [1]
> Почему её нельзя отдельным процессом сделать, а нужно вот
> так вот извращаться - я не совсем понимаю.
Может потому что я ещё начинающий...
Ega23 (2010-12-05 22:55:00) [2]
> а мини игры(или шутки какие-то) в свои приложения многие
> вставляют...
Почему её нельзя отдельным процессом сделать, а нужно вот так вот извращаться - я не совсем понимаю.
v_a_belousov (2010-12-05 22:47:00) [3]
> росто для игрушек (и для форматирования винта) есть уже
> готовые приложения, вроде программы на Delphi не в однозадачной
> среде выполняются, для подобных извратов...
не знаю что имеется ввиду, но я же никого не прошу пользоваться своим плеером например. я пишу его для себя, а мини игры(или шутки какие-то) в свои приложения многие вставляют...
Игорь Шевченко (2010-12-05 21:45:00) [4]
> зачем же так злобно то?)
да нет, ничего злобного в виду не имелось. Просто для игрушек (и для форматирования винта) есть уже готовые приложения, вроде программы на Delphi не в однозадачной среде выполняются, для подобных извратов...
v_a_belousov (2010-12-05 21:40:00) [5]
> А при нажатии другой комбинации клавиш форматнуть винт
зачем же так злобно то?)
Игорь Шевченко (2010-12-05 21:23:00) [6]
> так вот сделал что при нажатии определенной комбинации клавиш
> в плеере можно поиграть в змейку
А при нажатии другой комбинации клавиш форматнуть винт. В фоне.
v_a_belousov (2010-12-05 19:52:00) [7]
> Если флаг сброшен, то выход должен быть немедленным.
>
Так оно и есть но иногда что то не то происходит... точнее происходило пока не убрал Application.ProcessMessages;
> Ве это чудесно, но чем тогда таким архисложным у тебя занят
> осн.поток, если практически вся и игровая функциональность
> сосредоточена в дополнительном ?
> Зачем тут вообще дополнительный поток?
Занимается чем и должен проигрыванием музыки, видео, показом изображений... Я писал для себя небольшой плеер и захотел в него что нибудь добавить необычное... так вот сделал что при нажатии определенной комбинации клавиш в плеере можно поиграть в змейку)
Ega23 (2010-12-05 19:45:00) [8]Зачем тут вообще дополнительный поток?
Сергей М. (2010-12-05 19:39:00) [9]
> v_a_belousov (05.12.10 19:16) [7]
Ве это чудесно, но чем тогда таким архисложным у тебя занят осн.поток, если практически вся и игровая функциональность сосредоточена в дополнительном ?
Anatoly Podgoretsky (2010-12-05 19:33:00) [10]Если флаг сброшен, то выход должен быть немедленным.
v_a_belousov (2010-12-05 19:16:00) [11]Это изнутри самого Execute...
procedure TSnakeEngline.Execute;
var i, sL, sT, asL, asT: integer;
begin
//пока играем поток не завершается
while Play do begin
// ------------------------------ ЦИКЛ ИГРЫ
//если на паузе то ждем
while pause do begin
if not Play then begin {Terminate; Free;} exit; end;
sleep(10); end;
//устанавливаем скорость
Speed := 300-15*CurrentLevel;
//соблюдаем скорость
sleep(speed);
//если сняли с паузы, то выбираем куда идти
case SnakeMove of
//налево
MoveLeft:
begin
//движемся влево
CurrentMove := MoveLeft;
for i:=0 to Length(SnakeParts)-1 do
begin
if i>1 then
begin
sL := asL;
sT := asT;
end;
if i=0 then
begin
sL := SnakeParts[i].Left;
sT := SnakeParts[i].Top;
SnakeParts[i].Left := SnakeParts[i].Left-16;
end else
begin
asL := SnakeParts[i].Left;
asT := SnakeParts[i].Top;
SnakeParts[i].Left := sL;
SnakeParts[i].Top := sT;
end;
end;
end;
//направо
MoveRight:
begin
//движемся вправо
CurrentMove := MoveRight;
for i:=0 to Length(SnakeParts)-1 do
begin
if i>1 then
begin
sL := asL;
sT := asT;
end;
if i=0 then
begin
sL := SnakeParts[i].Left;
sT := SnakeParts[i].Top;
SnakeParts[i].Left := SnakeParts[i].Left+16;
end else
begin
asL := SnakeParts[i].Left;
asT := SnakeParts[i].Top;
SnakeParts[i].Left := sL;
SnakeParts[i].Top := sT;
end;
end;
end;
//вверх
MoveTop:
begin
//движемся вверх
CurrentMove := MoveTop;
for i:=0 to Length(SnakeParts)-1 do
begin
if i>1 then
begin
sL := asL;
sT := asT;
end;
if i=0 then
begin
sL := SnakeParts[i].Left;
sT := SnakeParts[i].Top;
SnakeParts[i].Top := SnakeParts[i].Top-16;
end else
begin
asL := SnakeParts[i].Left;
asT := SnakeParts[i].Top;
SnakeParts[i].Left := sL;
SnakeParts[i].Top := sT;
end;
end;
end;
//вниз
MoveBottom:
begin
//движемся вниз
CurrentMove := MoveBottom;
for i:=0 to Length(SnakeParts)-1 do
begin
if i>1 then
begin
sL := asL;
sT := asT;
end;
if i=0 then
begin
sL := SnakeParts[i].Left;
sT := SnakeParts[i].Top;
SnakeParts[i].Top := SnakeParts[i].Top+16;
end else
begin
asL := SnakeParts[i].Left;
asT := SnakeParts[i].Top;
SnakeParts[i].Left := sL;
SnakeParts[i].Top := sT;
end;
end;
end;
end;
//обновляем форму
//Synchronize(SnakeForm.Refresh);
SnakeForm.Refresh;
// проверяем не столкнулись ли со стеной или с самим собой
Synchronize(CheckConflict); //если да то сообщаем о проигрыше
if Conflict then begin pause:=true; MsgText:='Вы проиграли'; Synchronize(ShowMsg) end;
// проверяем съели ли мы что то
Synchronize(CheckPartake);
if Partake then begin Partake := false; MoveApple; AddPartToSnake;
//добавив часть змейке и переместив яблоко увеличиваем счет
inc(PartakeCount); GameInfoForm.PartakeCount_L.Caption := 'Съедено яблок: ' +
IntToStr(PartakeCount); Score := CalcScores;
//выводи информацию о кол-ве очков и текущем уровне
GameInfoForm.ScoreCount_L.Caption := 'Набрано очков: ' + IntToStr(Score);
GameInfoForm.CurrentLevel_L.Caption := 'Текущий уровень: ' + IntToStr(CurrentLevel);
end;
// ---------------------- ЦИКЛ ИГРЫ ---------------------------
end;
end;
Anatoly Podgoretsky (2010-12-05 19:12:00) [12]> v_a_belousov (05.12.2010 19:08:05) [5]
Я спрашивал, как процедура называется, как она стыкуется с Execute
v_a_belousov (2010-12-05 19:08:00) [13]
> Можно, а зачем?
Чтобы ждать снятия с паузы
> Вопрос два - почему Terminated не используешь, а изобретаешь
> какой то Play
Да правильно наверно while not Terminated do а почему Play сделал не помню уже честно говоря
> И вопрос три - а это кусок откуда?
Змейку захотел сделать, точнее сделал уже) из потока который обрабатывает действия в игре этот кусок
> Дмитрий С
Спасибо
Дмитрий С (2010-12-05 18:55:00) [14]на SwitchToThread заменить
А вообще лучше воспользоваться объектом ядра типа Event и функцией WaitForSingleObject
Anatoly Podgoretsky (2010-12-05 18:54:00) [15]Можно, а зачем?
Вопрос два - почему Terminated не используешь, а изобретаешь какой то Play
И вопрос три - а это кусок откуда?
v_a_belousov (2010-12-05 18:07:00) [16]А заменить на wait(10) например можно?
_Юрий (2010-12-05 17:59:00) [17]
> Application.ProcessMessages;
Ни в коем случае.