Прервать вызов неуправляемой DLL - PullRequest
13 голосов
/ 06 мая 2010

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

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

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

Можно ли завершить работающий код DLL?

Ответы [ 2 ]

27 голосов
/ 06 мая 2010

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

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

4 голосов
/ 06 мая 2010

Из MSDN

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

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

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

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

...