c# - query - entity framework stored procedure
Ejecute un procedimiento almacenado desde un formulario de Windows de forma asÃncrona y luego desconecte? (8)
Estoy llamando a un procedimiento almacenado de mi aplicación que puede tardar 30 minutos en ejecutarse.
No quiero que mi usuario deje la aplicación abierta durante todo ese período de tiempo. Así que me gustaría llamar al sproc, dejarlo volar y dejar que cierren la aplicación y vuelvan más tarde.
¿Cómo puedo hacer esto?
déjelos cerrar la aplicación y regresar más tarde
Si va a permitir que cierren completamente la aplicación, tendrá que iniciar un .exe separado o algo en un ThreadPool diferente que ejecute su código llamando al procedimiento almacenado. De lo contrario, su hilo morirá cuando cierre la aplicación.
La ventana principal de su aplicación no necesita estar abierta. Si lo lanzó como un hilo secundario, continuará ejecutándose mientras IsBackground == false
. Por lo general, prefiero hacer esto a través del Agente SQL Server o como una aplicación cliente-servidor (nada impide que una aplicación cliente-servidor se ejecute en la misma máquina, o incluso sea el mismo binario).
Ha sido un tiempo...
using System.Threading;
.....
Thread _t = null;
void StartProcedure()
{
_t = new Thread(new ThreadStart(this.StartProc));
_t.IsBackground = false;//If I remember correctly, this is the default value.
_t.Start();
}
bool ProcedureIsRunning
{
get { return _t.IsRunning; } //Maybe it''s IsActive. Can''t remember.
}
void StartProc(object param)
{
//your logic here.. could also do this as an anonymous method. Broke it out to keep it simple.
}
Otro método que podría hacer sería permitir que su aplicación se ejecute en segundo plano (posiblemente en el área de notificación) y luego salir o notificar cuando finalice el trabajo. Puede usar esto usando los métodos BeginExecuteNonQuery y EndExecuteNonQuery para permitir que se ejecute en un hilo separado.
Prefiero usar un servicio en segundo plano para el procesamiento fuera de línea, donde tu aplicación de usuario le dice al servicio qué hacer y luego se desconecta. El servicio puede registrar tiempos transcurridos y errores / estado, y reiniciar si es necesario. WCF está diseñado para esto y admite colas para comunicarse.
Si realmente desea cerrar completamente su aplicación, le sugiero que defina un trabajo en el Agente SQL Server, y simplemente ejecute una instrucción T-SQL para comenzar ese trabajo manualmente. La sintaxis es:
sp_start_job
{ [@job_name =] ''job_name''
| [@job_id =] job_id }
[ , [@error_flag =] error_flag]
[ , [@server_name =] ''server_name'']
[ , [@step_name =] ''step_name'']
[ , [@output_flag =] output_flag]
El trabajo ejecutará su procedimiento almacenado. Tendrás que ser un poco creativo para pasar cualquier argumento. Por ejemplo, inserte los parámetros en una tabla de "cola" y haga que el trabajo procese todas las filas en la cola.
En lugar de un trabajo, un desencadenador de inserción en su cola también debería funcionar.
Sugiero una nueva arquitectura. Cree una tabla de "cola de trabajos" donde registre las solicitudes para ejecutar el procedimiento almacenado. Luego, o bien tiene un servicio de Windows o un trabajo de SQL Server, verifique esa cola de trabajo de vez en cuando (o sea realmente ingenioso y use un activador) para iniciar el procedimiento almacenado. Haga que el procedimiento almacenado actualice el progreso de vez en cuando en la tabla de colas de trabajo, y su interfaz puede ver eso y decirle al usuario el progreso, y luego mostrar los resultados cuando haya terminado.
Este es en realidad un escenario bastante común. No se puede hacer nada basado en el cliente porque el cliente puede irse y desconectarse y perderá el trabajo logrado hasta el momento. La solución es usar la Activación de Service Broker : crea un servicio en la base de datos y adjunta un procedimiento activado. En su aplicación (o página ASP), envíe un mensaje al servicio e incruste los parámetros necesarios para su procedimiento. Una vez que la aplicación se haya confirmado, el mensaje activará el procedimiento de servicio. el procedimiento de servicio lee los parámetros del mensaje e invoca su procedimiento. dado que la activación ocurre en un hilo del servidor no relacionado con su conexión original, esto es confiable. De hecho, el servidor puede incluso apagar y reiniciar mientras se ejecuta su procedimiento y el trabajo se retrotraerá y luego reanudará, ya que el mensaje de activación activará nuevamente el procedimiento de servicio después del reinicio.
Actualizar
He publicado los detalles de cómo hacer esto, incluido el código de muestra en mi blog: ejecución de procedimiento asíncrono .
Puede usar los métodos BeginExecuteXXX
/ EndExecuteXXX
(dependiendo de si devuelve un resultado o no) de SqlCommand
, pasando un delegado de devolución de llamada.