Отменить вызов неуправляемой библиотеки DLL - программирование
Подтвердить что ты не робот

Отменить вызов неуправляемой библиотеки DLL

У меня есть неуправляемая DLL с функцией, которая может работать в течение длительного времени, если входной параметр является большим значением, иногда это желательно, но не всегда.

Как я могу в С# вызвать эту функцию, чтобы я мог ее прервать при необходимости?

До сих пор я пытался поместить вызов в отдельный поток, но ни прерывание, ни прерывание, похоже, не прекратили процесс, который работает на 100% CPU до тех пор, пока dll не будет завершено.

Возможно ли завершить работу кода dll?

4b9b3361

Ответ 1

Неуправляемый код отменяется только в том случае, если это "аварийное состояние ожидания". Это не будет, когда он сжигает 100% циклов процессора. P/Invoking TerminateThread будет работать, предполагая, что вы можете получить дескриптор потока, который .NET очень затрудняет. В любом случае это не поможет, вы будете утечка стека потоков. На одном мегабайте вы быстро исчерпаете виртуальную память. Даже если это только случайная потребность, вы все еще можете столкнуться с серьезными проблемами, поскольку поток имеет мутированное глобальное состояние программы, и вы не знаете, как его восстановить.

Единственный хороший способ прервать неуправляемый код - запустить его в отдельном процессе и запустить его в голову с помощью Process.Kill(). Операционная система очистит шрапнель. Вам нужно будет написать небольшую программу хостинга для DLL и использовать один из средств взаимодействия между процессами, чтобы поговорить с ним. Сокеты, именованные каналы, удаленное взаимодействие .NET, WCF, выбирают.

Ответ 2

Из MSDN

Если Abort вызывается в управляемом потоке в то время как он выполняет неуправляемый код, исключение ThreadAbortException не выбрасывается пока поток не вернется к управляемому код.

Итак, кажется, прерывание управляемого потока невозможно.
В качестве альтернативы вы можете попробовать запустить неуправляемый поток с помощью API Win32 CreateThread(), WaitForSingleObject() и TerminateThread(). Используйте подписи здесь.

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

В общем, я бы посоветовал против такого прерывания. Возможно, у вас есть возможность изменить неуправляемую DLL, чтобы обеспечить изящную отмену.