Остановить зависший поток
От: debugx Россия http://oignatov.blogspot.com
Дата: 04.10.10 12:28
Оценка:
Всем привет,
стартую поток, которой обращается к сторонней нативной длл, которая в один прекрасный момент зависает.
Вопрос, как теперь грохнуть этот поток?
после вызова Abort() у потока появляется статус AbortRequested, но сам поток не останавливается и не отваливается с ThreadAbortException.
Как лучше решить эту задачу?
Re: Остановить зависший поток
От: _FRED_ Черногория
Дата: 04.10.10 12:49
Оценка: +1
Здравствуйте, debugx, Вы писали:

D>стартую поток, которой обращается к сторонней нативной длл, которая в один прекрасный момент зависает.

D>Вопрос, как теперь грохнуть этот поток?
D>после вызова Abort() у потока появляется статус AbortRequested, но сам поток не останавливается и не отваливается с ThreadAbortException.

Например, вызывать в отдельном домене и выгружать домен.

D>Как лучше решить эту задачу?


"Лучшего" способа данной задачи не найти, покуда не будет доподлинно известно, из-за чего происходит "зависание", поскольку неизвестно, безопастно ли вызвать другие методы данной библиотеки после такого "крутого" обращения с ней.
Help will always be given at Hogwarts to those who ask for it.
Re: Остановить зависший поток
От: Jolly Roger  
Дата: 04.10.10 12:53
Оценка: +3
Здравствуйте, debugx, Вы писали:

D>Всем привет,

D>стартую поток, которой обращается к сторонней нативной длл, которая в один прекрасный момент зависает.
D>Вопрос, как теперь грохнуть этот поток?
D>после вызова Abort() у потока появляется статус AbortRequested, но сам поток не останавливается и не отваливается с ThreadAbortException.

Грохнуть можно WinApi функцией TerminateThread, но её и в нативном коде лучше не использовать, а каковы будут последствия в NET, я предсказать не берусь.

D>Как лучше решить эту задачу?


Лучше всего грохнуть эту "длл, которая в один прекрасный момент зависает"
"Нормальные герои всегда идут в обход!"
Re[2]: Остановить зависший поток
От: Nikolay_P_I  
Дата: 04.10.10 13:04
Оценка: +3
Здравствуйте, _FRED_, Вы писали:

_FR>"Лучшего" способа данной задачи не найти, покуда не будет доподлинно известно, из-за чего происходит "зависание", поскольку неизвестно, безопастно ли вызвать другие методы данной библиотеки после такого "крутого" обращения с ней.


Не очень понятно, что автор имел ввиду под "нативная" — если unmanaged — плевала она на домены.

Запускать второй процесс, общаться с ним, мониторить, грохать и поднимать. Кто его знает — в каком оно состоянии после зависания окажется.
Re[3]: Остановить зависший поток
От: debugx Россия http://oignatov.blogspot.com
Дата: 04.10.10 14:00
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:

N_P>Здравствуйте, _FRED_, Вы писали:


_FR>>"Лучшего" способа данной задачи не найти, покуда не будет доподлинно известно, из-за чего происходит "зависание", поскольку неизвестно, безопастно ли вызвать другие методы данной библиотеки после такого "крутого" обращения с ней.


N_P>Не очень понятно, что автор имел ввиду под "нативная" — если unmanaged — плевала она на домены.


N_P>Запускать второй процесс, общаться с ним, мониторить, грохать и поднимать. Кто его знает — в каком оно состоянии после зависания окажется.

+1
вызов AppDomain.Unload(_ad); также уходит в себя.
мда, видимо придется в отдельном процессе запускать
представляете, так есть система с достаточно обширной архитектурой, и в нескольких местах идет обращение к unmanaged dll. Как теперь всё это вынести в отдельный процесс, который потянет в себе множество дллок, сложно представить.
Хотя в принципе... сейчас попробую.
Re: Остановить зависший поток
От: debugx Россия http://oignatov.blogspot.com
Дата: 04.10.10 14:08
Оценка:
Здравствуйте, debugx, Вы писали:

D>Всем привет,

D>стартую поток, которой обращается к сторонней нативной длл, которая в один прекрасный момент зависает.
D>Вопрос, как теперь грохнуть этот поток?
D>после вызова Abort() у потока появляется статус AbortRequested, но сам поток не останавливается и не отваливается с ThreadAbortException.
D>Как лучше решить эту задачу?

А нельзя ли как-то выгрузить эту unmanaged dll?
Я знаю как она называется.
Попробовал пока так:
[DllImport("kernel32")] static extern IntPtr GetModuleHandle(string
module);
[DllImport("kernel32")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool FreeLibrary(IntPtr handle);

....
IntPtr HModule = GetModuleHandle("nativeModule.dll");
bool success = FreeLibrary(HModule);
if(success)
...
else
...


FreeLibrary возвращает true, но поток продолжает висеть...
Re[2]: Остановить зависший поток
От: Pavel Dvorkin Россия  
Дата: 05.10.10 03:05
Оценка: +1
Здравствуйте, debugx, Вы писали:

D>А нельзя ли как-то выгрузить эту unmanaged dll?


Выгрузить можно, но ничего хорошего не будет, поток не исчезнет.
With best regards
Pavel Dvorkin
Re[4]: Остановить зависший поток
От: Nikolay_P_I  
Дата: 05.10.10 09:40
Оценка:
N_P>>Не очень понятно, что автор имел ввиду под "нативная" — если unmanaged — плевала она на домены.
N_P>>Запускать второй процесс, общаться с ним, мониторить, грохать и поднимать. Кто его знает — в каком оно состоянии после зависания окажется.
D>+1
D>вызов AppDomain.Unload(_ad); также уходит в себя.
D>мда, видимо придется в отдельном процессе запускать
D>представляете, так есть система с достаточно обширной архитектурой, и в нескольких местах идет обращение к unmanaged dll. Как теперь всё это вынести в отдельный процесс, который потянет в себе множество дллок, сложно представить.

Это самый правильный способ. Другое дело, что, например, мы в похожей ситуации ограничивались запуском потока с ограничением на максимальное время выполнения — там есть такая перегрузка. Это проще, но не всегда годится, и не гарантирует, что после первой аварии все нормально будет работать при следующих вызовах. Смотрите по ситуации.
Re[5]: Остановить зависший поток
От: sCreator  
Дата: 05.10.10 19:16
Оценка:
Здравствуйте, Nikolay_P_I, Вы писали:
N_P>Это самый правильный способ. Другое дело, что, например, мы в похожей ситуации ограничивались запуском потока с ограничением на максимальное время выполнения — там есть такая перегрузка. Это проще, но не всегда годится, и не гарантирует, что после первой аварии все нормально будет работать при следующих вызовах. Смотрите по ситуации.

Если не трудно, подскажите перезагрузку запуска потока с ограничением времени — сегодня весь вечер убил на поиски
Re: Остановить зависший поток
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 05.10.10 21:10
Оценка:
Здравствуйте, debugx, Вы писали:

D>Всем привет,

D>стартую поток, которой обращается к сторонней нативной длл, которая в один прекрасный момент зависает.
D>Вопрос, как теперь грохнуть этот поток?
D>после вызова Abort() у потока появляется статус AbortRequested, но сам поток не останавливается и не отваливается с ThreadAbortException.
D>Как лучше решить эту задачу?

Лучше пофиксить эту umnanaged dll таким образом, чтобы она реализовала нормальный способ завершения по запросу. Это называется модным словом "cooperative cancellation", и заключается в том, что внешний код может "запросить" остановку потока (в конечном итоге путем изменения некоторого флага), а рабочий поток периодически проверяет этот флаг и завершает свою работу нормальным образом при получении запроса отмены.

Unmanaged thread можно грохнуть только путем вызова API функции TerminateThread, но тогда как можно быть уверенным в том, что ваше приложение осталось в согласованном состоянии? Выделение этого потока в отдельный процесс с последующим гроханием процесса поможет решить проблему с ресурсами, но может оставить приложение в целом в рассогласованном состоянии (например, приложение должно поддерживать некоторые внешние ресурсы в согласованном состоянии, например, нужно по закрытию приложения делать что-либо в БД или файле). Плюс придеться возиться с межпроцессным взаимодействием... Так что этот вариант лучше оставить на потом, если других путей решения этой проблемы не останется.
Re[3]: Остановить зависший поток
От: Vain Россия google.ru
Дата: 07.10.10 11:37
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

D>>А нельзя ли как-то выгрузить эту unmanaged dll?

PD>Выгрузить можно, но ничего хорошего не будет, поток не исчезнет.
Даже вроде опасно, если поток ковыряется в данных длл.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.