2010-01-13 2 views
1

Можно создать дубликат:
How to stop long executing threads gracefully?Delphi - Terminate блокированный поток

Здравствуйте.

У меня есть фоновый поток, который должен выполнять операцию, он работает нормально все время, за исключением одного случая: когда ресурс поврежден. Когда это происходит, поток получает Blocked в вызове Load (to this resource) в методе Execute.

Когда это произойдет, нить не ответит на метод Terminate (вызов из основного потока) и будет заблокирован.

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

+1

О каком ресурсе вы говорите? –

+0

Подобный вопрос [здесь] (http://stackoverflow.com/questions/255276/how-to-stop-long-executing-threads-gracefully) – SimaWB

ответ

1

Ищите TerminateThread() Функция WinAPI. Некоторое полезное объяснение можно найти here или посмотреть на документацию MSDN.

Конечно, после завершения вы должны посмотреть, не выделены ли какие-либо ресурсы, выделенные в потоке, бесплатно и бесплатно.


Update

Да, с помощью TerminateThread плохая практика (как указано в комментариях). Я согласен с этим мнением. Но «никогда не используйте его, даже если вам действительно нужно его использовать», это слишком сильно, с моей точки зрения, и очень теоретично. Реальный мир, полный недостатков дизайна и багги сторонних библиотек.
Информация, заданная в вопросе, недостаточно для принятия правильного решения об этой конкретной ситуации. Например. это может быть временное обходное решение без каких-либо альтернатив и т. д.
Следовательно, с теоретической точки зрения правильный ответ: «Невозможно правильно завершить процесс, если вы не можете контролировать, как« замораживать »шаг в фоновом потоке «.
С практической точки зрения правильный ответ: «Невозможно правильно завершить процесс, если вы не можете контролировать, как« замораживать »шаг в фоновом потоке, но если вы понимаете, что не можете, но по-прежнему нуждается в такой функциональности - используйте TerminateThread() API вызова»

О TerminateThread против TerminateProcess:
- Создание/процесс завершения требует больше ресурсов, чем создание/завершение нити
- Создание/завершение процесса сложнее => более место для ошибок
- TerminateProcess не заканчивается немедленно и ждет ввода-вывода o заполнение (MSDN) => не выбор для сценария, когда удаленная общая папка становится недоступной при чтении и других подобных сценариях ввода-вывода.
- Создание и процесс завершения требует больше привилегий пользователей, чем создание потока, сравнить MSDN here и here

О высвобождении ресурсов: стек
Thread освобождается автоматически при завершении нити (как mentonied в MSDN).Ресурсы - это прежде всего ресурсы, выделенные основным потоком для связи с фоновым потоком. Например. структуры памяти, мьютексы и т. д.

+0

Правильно, * посмотрите на * эту функцию, а затем сделайте вывод, что вы должны никогда, никогда не называйте это. Вы не можете освобождать ресурсы, выделенные потоком, потому что вы не знаете, что они собой представляют и как их освобождать. (Как вы, например, освободите стек потока?) –

+1

Этот вопрос * * тот же. Независимо от того, имеете ли вы доступ к исходному коду, не имеет значения - ограничения в обоих вопросах одинаковы: код не может быть изменен, и мы не можем заранее знать, нужно ли остановить поток. Кроме того, верхний ответ на другой вопрос также относится к этому вопросу. Лучше всего сделать это, чтобы изменить программу, чтобы поток не блокировался в первую очередь. Если это невозможно, переведите операцию в отдельный процесс. Гораздо безопаснее прекратить весь процесс, чем завершить только один поток. –

Смежные вопросы