2010-05-06 3 views
12

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

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

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

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

ответ

23

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

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

+4

+1 для упоминания головного выстрела;) – Nate

+1

Другой вариант - сделать то же самое в отдельном домене приложения. –

+1

Нет, appdomains ничего не значат для неуправляемого кода. –

4

От MSDN

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

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

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

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

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