Всем привет,
стартую поток, которой обращается к сторонней нативной длл, которая в один прекрасный момент зависает.
Вопрос, как теперь грохнуть этот поток?
после вызова Abort() у потока появляется статус AbortRequested, но сам поток не останавливается и не отваливается с ThreadAbortException.
Как лучше решить эту задачу?
Здравствуйте, debugx, Вы писали:
D>стартую поток, которой обращается к сторонней нативной длл, которая в один прекрасный момент зависает. D>Вопрос, как теперь грохнуть этот поток? D>после вызова Abort() у потока появляется статус AbortRequested, но сам поток не останавливается и не отваливается с ThreadAbortException.
Например, вызывать в отдельном домене и выгружать домен.
D>Как лучше решить эту задачу?
"Лучшего" способа данной задачи не найти, покуда не будет доподлинно известно, из-за чего происходит "зависание", поскольку неизвестно, безопастно ли вызвать другие методы данной библиотеки после такого "крутого" обращения с ней.
Help will always be given at Hogwarts to those who ask for it.
Здравствуйте, debugx, Вы писали:
D>Всем привет, D>стартую поток, которой обращается к сторонней нативной длл, которая в один прекрасный момент зависает. D>Вопрос, как теперь грохнуть этот поток? D>после вызова Abort() у потока появляется статус AbortRequested, но сам поток не останавливается и не отваливается с ThreadAbortException.
Грохнуть можно WinApi функцией TerminateThread, но её и в нативном коде лучше не использовать, а каковы будут последствия в NET, я предсказать не берусь.
D>Как лучше решить эту задачу?
Лучше всего грохнуть эту "длл, которая в один прекрасный момент зависает"
Здравствуйте, _FRED_, Вы писали:
_FR>"Лучшего" способа данной задачи не найти, покуда не будет доподлинно известно, из-за чего происходит "зависание", поскольку неизвестно, безопастно ли вызвать другие методы данной библиотеки после такого "крутого" обращения с ней.
Не очень понятно, что автор имел ввиду под "нативная" — если unmanaged — плевала она на домены.
Запускать второй процесс, общаться с ним, мониторить, грохать и поднимать. Кто его знает — в каком оно состоянии после зависания окажется.
Здравствуйте, Nikolay_P_I, Вы писали:
N_P>Здравствуйте, _FRED_, Вы писали:
_FR>>"Лучшего" способа данной задачи не найти, покуда не будет доподлинно известно, из-за чего происходит "зависание", поскольку неизвестно, безопастно ли вызвать другие методы данной библиотеки после такого "крутого" обращения с ней.
N_P>Не очень понятно, что автор имел ввиду под "нативная" — если unmanaged — плевала она на домены.
N_P>Запускать второй процесс, общаться с ним, мониторить, грохать и поднимать. Кто его знает — в каком оно состоянии после зависания окажется.
+1
вызов AppDomain.Unload(_ad); также уходит в себя.
мда, видимо придется в отдельном процессе запускать
представляете, так есть система с достаточно обширной архитектурой, и в нескольких местах идет обращение к unmanaged dll. Как теперь всё это вынести в отдельный процесс, который потянет в себе множество дллок, сложно представить.
Хотя в принципе... сейчас попробую.
Здравствуйте, 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);
N_P>>Не очень понятно, что автор имел ввиду под "нативная" — если unmanaged — плевала она на домены. N_P>>Запускать второй процесс, общаться с ним, мониторить, грохать и поднимать. Кто его знает — в каком оно состоянии после зависания окажется. D>+1 D>вызов AppDomain.Unload(_ad); также уходит в себя. D>мда, видимо придется в отдельном процессе запускать D>представляете, так есть система с достаточно обширной архитектурой, и в нескольких местах идет обращение к unmanaged dll. Как теперь всё это вынести в отдельный процесс, который потянет в себе множество дллок, сложно представить.
Это самый правильный способ. Другое дело, что, например, мы в похожей ситуации ограничивались запуском потока с ограничением на максимальное время выполнения — там есть такая перегрузка. Это проще, но не всегда годится, и не гарантирует, что после первой аварии все нормально будет работать при следующих вызовах. Смотрите по ситуации.
Здравствуйте, Nikolay_P_I, Вы писали: N_P>Это самый правильный способ. Другое дело, что, например, мы в похожей ситуации ограничивались запуском потока с ограничением на максимальное время выполнения — там есть такая перегрузка. Это проще, но не всегда годится, и не гарантирует, что после первой аварии все нормально будет работать при следующих вызовах. Смотрите по ситуации.
Если не трудно, подскажите перезагрузку запуска потока с ограничением времени — сегодня весь вечер убил на поиски
Здравствуйте, debugx, Вы писали:
D>Всем привет, D>стартую поток, которой обращается к сторонней нативной длл, которая в один прекрасный момент зависает. D>Вопрос, как теперь грохнуть этот поток? D>после вызова Abort() у потока появляется статус AbortRequested, но сам поток не останавливается и не отваливается с ThreadAbortException. D>Как лучше решить эту задачу?
Лучше пофиксить эту umnanaged dll таким образом, чтобы она реализовала нормальный способ завершения по запросу. Это называется модным словом "cooperative cancellation", и заключается в том, что внешний код может "запросить" остановку потока (в конечном итоге путем изменения некоторого флага), а рабочий поток периодически проверяет этот флаг и завершает свою работу нормальным образом при получении запроса отмены.
Unmanaged thread можно грохнуть только путем вызова API функции TerminateThread, но тогда как можно быть уверенным в том, что ваше приложение осталось в согласованном состоянии? Выделение этого потока в отдельный процесс с последующим гроханием процесса поможет решить проблему с ресурсами, но может оставить приложение в целом в рассогласованном состоянии (например, приложение должно поддерживать некоторые внешние ресурсы в согласованном состоянии, например, нужно по закрытию приложения делать что-либо в БД или файле). Плюс придеться возиться с межпроцессным взаимодействием... Так что этот вариант лучше оставить на потом, если других путей решения этой проблемы не останется.
Здравствуйте, Pavel Dvorkin, Вы писали:
D>>А нельзя ли как-то выгрузить эту unmanaged dll? PD>Выгрузить можно, но ничего хорошего не будет, поток не исчезнет.
Даже вроде опасно, если поток ковыряется в данных длл.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]