2010-05-06 10 views
12

Tengo una DLL no administrada con una función que puede ejecutarse durante un tiempo prolongado si el parámetro de entrada es de gran valor, a veces es deseable pero no siempre.Anular la llamada a DLL no administrado

¿Cómo puedo en C# llamar esta función para poder cancelarla cuando sea necesario?

Hasta ahora he tratado de poner la llamada en una hebra separada, pero ni la interrupción ni la interrupción parecen detener el proceso, que se ejecuta al 100% de la CPU hasta que se completa el dll.

¿Es posible finalizar el código dll en ejecución?

Respuesta

23

El código no administrado solo se puede cancelar si se trata de un "estado de espera alertable". No será cuando esté grabando ciclos de 100% de CPU. P/Invocar TerminateThread funcionaría, suponiendo que se puede obtener el manejador de subprocesos, lo que hace .NET muy difícil. No ayudará de todos modos, perderás la pila de hilos. En un megabyte, se quedará rápidamente sin memoria virtual. Incluso si esto solo es una necesidad ocasional, aún es probable que se encuentre con problemas importantes ya que el hilo ha mutado el estado del programa global y no sabe cómo restaurarlo.

La única buena manera de cancelar el código no administrado es ejecutarlo en un proceso separado y dispararlo en la cabeza con Process.Kill(). El sistema operativo limpiará la metralla. Tendrá que escribir un pequeño programa de alojamiento para el archivo DLL y utilizar uno de los recursos de interoperabilidad del proceso para hablar con él. Los sockets, pipes nombrados, .NET remoting, WCF, hacen su elección.

+4

+1 para mencionar un head-shot;) – Nate

+1

Otra opción es hacer lo mismo en un dominio de aplicación separado. –

+1

No, appdomains no significa nada en absoluto para el código no administrado. –

4

Desde el MSDN

Si Abortar se llama en un subproceso administrado mientras se está ejecutando el código no administrado, un ThreadAbortException no se lanza hasta que el hilo vuelve a código administrado .

Parece que no es posible abortar el subproceso administrado.
Como alternativa puede intentar iniciar un subproceso no administrado con Win32 APIs CreateThread(), WaitForSingleObject() y TerminateThread(). Use las firmas de here.

No intenté esto por mí mismo, pero seguramente presenta algunos riesgos, ya que no se puede determinar en qué punto de ejecución está matando el hilo. También podría conducir a pérdidas de recursos. MSDN enumera algunos de los efectos secundarios en la referencia TerminateThread().

En general, aconsejaría este tipo de interrupción. Tal vez tenga la posibilidad de cambiar la DLL no administrada para permitir un aborto elegante.

Cuestiones relacionadas