Вы не можете остановить фоновый поток снаружи этого потока, то есть вы не можете прервать поток. Чтобы остановить фоновый поток, соответствующий код должен иметь условие остановки и выйти сам.
Чтобы управлять этим условием остановки из другого потока, вам нужно как-то "общаться" между двумя потоками. Это можно сделать разными способами. Самым простым является использование простой числовой переменной, которая проверяется фоновым рабочим кодом, но может быть установлена с помощью любого другого «внешнего» кода. Пример этого можно найти в этом ответе здесь .
Вместо простой переменной можно также использовать какое-то общедоступное место, например, f.e. глобальные теги . Кроме того, некоторые более сложные объекты синхронизации потоков, такие как сигналы , мьютексы и семфоры , определены для языка сценариев и описаны в справочной документации здесь:
![Help on threading](https://i.stack.imgur.com/OifK4.jpg)
Как внешний поток вставляет 'разрыв' в фоновый рабочий поток, также можно сделать разными способами. Один из них - как в примере выше - взаимодействовать с пользователем через какой-то открытый диалог. Другой, как упомянуто автором, должен иметь некоторый код слушателя событий, чтобы вызвать это.
В следующем примере к изображению прикрепляется прослушиватель клавиш, так что (с этим изображением, расположенным спереди и выделенным), пользователь может нажать кнопку ESC, чтобы остановить поток.
Я использую предоставленный скрипт с минимальными изменениями для показа этого:
// $BACKGROUND$
//
Class CBackground : Thread
{
Number isRunning
Number imgID
Number keyListenID
Image tmpIMG
//
Void Init( Object self, Number iID ){
imgID = iID
tmpIMG := GetImageFromID( imgID )
ImageDisplay disp = tmpIMG.ImageGetImageDisplay(0)
keyListenID = disp.ImageDisplayAddKeyHandler( self, "KeyListenAction" )
}
//
Void StopRunning( Object self ){
isRunning = 0
}
//
Number GetIsRunning( Object self ){
return isRunning
}
/////////////////////////////////////////////////////////////////////////////
Number KeyListenAction(Object self, ImageDisplay disp, Object keydesc )
{
number b_keyhandled = 0
If ( keydesc.MatchesKeyDescriptor("esc") )
{
disp.ImageDisplayRemoveKeyHandler( keyListenID )
self.StopRunning()
Result( "\nSend stopping flag, unregister Key-Listeners" )
b_keyhandled = 1
}
return b_keyhandled;
}
//
Void RunThread( Object self ){
Result("Background thread is starting ......")
isRunning = 1
while (isRunning)
{
tmpIMG = random()
sleep(0.5)
}
Result(" finished !!" + "\n")
}
}
//
Void Main(){
Object cbkg = alloc(CBackground)
Image IMG := RealImage("test",4,64,64)
IMG = random()
IMG.ShowImage()
IMG.SetWindowSize(512,512)
cbkg.Init(IMG.GetImageID())
cbkg.StartThread()
}
//
Main()
Однако есть несколько вещей, которые я бы сделал по-другому:
- Запустите фоновый поток правильной командой, а не старым методом $$ BACKGROUND $$.
- Инкапсулируйте как можно больше в класс
- Добавить несколько проверок безопасности
- Также добавьте обработчик событий закрытых окон , так что закрытие окна изображения также останавливает поток
- Добавьте некоторый код отладки, чтобы показать, когда объект создается и когда он удаляется из памяти
- У прослушивателя ключей есть возможность приостановить / отменить действие.