• 0
Akad

Убить поток TThread кроссплатформено

Вопросы

Есть TThread, который что-то там своё делает. При этом он может "подвиснуть", особенно на 3g TCP соединениях. И соответственно часто случается, что его надо "пристрелить" не дожидаясь пока он сам сообразит что пора закругляться. Под винду есть чудесная TerminateThread. Но как ту же задачу выполнить под Android? iOS?
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

13 ответов на этот вопрос

  • 0

Если я не прав поправят, но я делаю так

uses Threading;

var

GetCodeTask: ITask;

      GetCodeTask := TTask.Create(
          procedure
         begin

              ...

         end);
 

  if GetCodeTask <> nil then
    if GetCodeTask.Status = TTaskStatus.Running then
      GetCodeTask.Cancel;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

повис, да и пусть висит себе.

все равно прервать системную функцию вам не удастся раньше её функции желания

зато вы легко можете игнорировать результат выполнения такого потока, если/когда он все же вернется

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

Если поток висит на методе Read - разорвать TCP сессию, Read вернет ошибку и поток можно завершить корректно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
4 часа назад, Камышев Александр сказал:

разорвать TCP сессию,

А как? Ну, на винде в теории можно из другого потока закрыть хендл соединения (если используемый для сетевого обмена компонент дает возможность получить хендл).

А вот кроссплатформенный штатный HTTPClient -???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
1 час назад, kami сказал:

А как? Ну, на винде в теории можно из другого потока закрыть хендл соединения (если используемый для сетевого обмена компонент дает возможность получить хендл).

А вот кроссплатформенный штатный HTTPClient -???

Сдаюсь, кто их знает чего там в исходниках.

На винде хэндл закрыть, на unix pthread_cancel выводит из операции ввода-вывода или sleep в pthread.

TIdHTTP или TNetHTTPclient?

IdHTTP1->Socket->Close() - не поможет?

Изменено пользователем Камышев Александр

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
В 27 ноября 2017 г. в 15:53, FREEFAR сказал:

GetCodeTask: ITask;

Нужен полноценный поток, как отдельный класс.

Тем более

В 27 ноября 2017 г. в 15:53, FREEFAR сказал:

  if GetCodeTask <> nil then
    if GetCodeTask.Status = TTaskStatus.Running then
      GetCodeTask.Cancel;

Это явный краш всей системы. Когда поток высвободит ресурсы между if и cancel.

В 27 ноября 2017 г. в 16:05, krapotkin сказал:

повис, да и пусть висит себе.

Ага. Только когда он отвиснет, не будет ни сам существовать ни все переменные, которые в нём. А равно как и форма, один из компонентов которой он заполнял.

В 27 ноября 2017 г. в 16:05, krapotkin сказал:

зато вы легко можете игнорировать результат выполнения такого потока, если/когда он все же вернется

Под андроидом сложно игнорировать краш всей программы и закрытие её. По крайней мере у меня не получается. Если в одном из потоков тотальный краш - это всё.
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
3 минуты назад, Akad сказал:

Нужен полноценный поток, как отдельный класс.

А чем TTask не полноценен?

 

4 минуты назад, Akad сказал:

Это явный краш всей системы. Когда поток высвободит ресурсы между if и cancel.

Есть пример подтверждающий это утверждение? Просто у меня пока пол года  все работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0

а почему поток должен крешить систему, я не пойму?
не нужно из потока обращаться к переменным. можно задать ему обработчик OnTerminate
конечно и форма, из которой его вызвали может перестать существовать, но тогда просто обработчик вешать на то что существовать точно БУДЕТ

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
1 час назад, FREEFAR сказал:

А чем TTask не полноценен?

Как миниум нет полноценного класса. Но вопрос не в этом. Cancel не работает. Поток не убивает. Только что проверил на запросе который длится 6-7 сек. Через секунду потоку делаю Cancel, но он всё равно доходит до конца и даже память освобождает. В общем не работает.

1 час назад, FREEFAR сказал:

Есть пример подтверждающий это утверждение? Просто у меня пока пол года  все работает.

Оно очевидно из кода. :D

Любое межпоточное взаимодействие нужно осуществлять на локах (если нужно быстро, но в дельфе нет, только через апи). Ну или по извращённому/тормозному/но дельфёвому. Через Synchronize например. Ну если не интересно отлаживать приложение на устройствах клиента с разницей во времени часов в 12, и явным не желанием пользователя этим заниматься. :D

1 час назад, krapotkin сказал:

а почему поток должен крешить систему, я не пойму?
не нужно из потока обращаться к переменным. можно задать ему обработчик OnTerminate
конечно и форма, из которой его вызвали может перестать существовать, но тогда просто обработчик вешать на то что существовать точно БУДЕТ

Потому что единственная цель жизни потока в данном случае - обратиться к серверу с 'select тра-ля-ля' и заполнить таблицу. Таблиц на форме может быть 5-6. Соответственно потоков столько-же. Костылей наставить можно, но правильнее при закрытии формы поток прибить. Точнее под винду так и поступаю, но сейчас портирую на мобилки. И без конструкции вида

TerminateThread(ServerReader.Handle,$DEAD);

пока не представляю как это сделать.

 

Изменено пользователем Akad

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
8 минут назад, Akad сказал:

межпоточное взаимодействие нужно осуществлять на локах (если нужно быстро, но в дельфе нет, только через апи).

С каких пор в Delphi перестали существовать TCriticalSection, TMutex, TEvent? Которые, кстати, работают кроссплатформенно, используя штатные средства, предоставляемые ОС.

Изменено пользователем kami

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
26 минут назад, kami сказал:

С каких пор в Delphi перестали существовать TCriticalSection, TMutex, TEvent?

Да, они действительно существуют. Но во времена XE2 они как-то очень "странно" работали. Поэтому написал свои. Возможно сейчас ситуация стала лучше.Не проверял. Беру свои слова обратно.

Но TerminateThread в любом случае нет, а нужен он.
 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
  • 0
4 часа назад, Akad сказал:

'select тра-ля-ля' и заполнить таблицу.

я заполняю структуры данных, не имеющие отношения к форме, да еще и в главном потоке, так что все пучком пока.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти


  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу