Tengo un servicio de ventanas multiproceso en .Net 3.5 y estoy teniendo problemas para detener el servicio correctamente cuando se crea más de un subproceso.Detener un servicio de ventanas con subprocesos múltiples
Este servicio solía crear solo un hilo para hacer todo el trabajo, y acabo de cambiarlo para que sea multihilo. Funciona perfectamente, pero cuando se detiene el servicio, si se está ejecutando más de un subproceso, se bloqueará el servicio hasta que se completen todos los subprocesos.
Cuando se inicia el servicio, puedo crear un subproceso de fondo para manejar el proceso principal:
protected override void OnStart(string[] args)
{
try
{
//Global variable that is checked by threads to learn if service was stopped
DeliveryConstant.StopService = false;
bool SetMaxThreadsResult = ThreadPool.SetMaxThreads(10, 10);
ThreadStart st = new ThreadStart(StartThreadPool);
workerThread = new Thread(st);
workerThread.IsBackground = true;
serviceStarted = true;
workerThread.Start();
}
catch (Exception ex)
{
//Log something;
}
Aquí es el método StartThreadPool:
//Tried with and without this attribute with no success...
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
public void StartThreadPool()
{
while (serviceStarted)
{
ProcessInfo input = new ProcessInfo();
try
{
int? NumPendingRequests = GetItems(50, (Guid?)input.ProcessID);
if (NumPendingRequests > 0)
{
input.ProcessType = 1;
input.ProcessID = Guid.NewGuid();
ThreadPool.QueueUserWorkItem(new WaitCallback(new DispatchManager().ProcessRequestList), input);
}
}
catch (Exception ex)
{
//Some Logging here
}
}
DeliveryConstant.StopService = true;
}
he creado una variable estática en una clase separada para notificar a los hilos que el servicio fue detenido. Cuando el valor de esta variable es cierto, todas las discusiones deben detener el bucle principal (una para cada bucle):
public static bool StopService;
Finalmente, el método OnStop:
protected override void OnStop()
{
DeliveryConstant.StopService = true;
//flag to tell the worker process to stop
serviceStarted = false;
workerThread.Join(TimeSpan.FromSeconds(30));
}
En el método ProcessRequestList, en el Al final de cada foreach, compruebo el valor de la variable StopService. Si es cierto, rompo el ciclo.
Aquí está el problema: Los hilos se crean en trozos de 50 elementos. Cuando tengo 50 elementos o menos en la base de datos, solo se crea un hilo, y todo funciona maravillosamente. Cuando tengo más de 50 elementos, se crearán varios subprocesos, y cuando intento detener el servicio, no se detiene hasta que se completan todos los subprocesos de fondo.
De los registros, puedo ver que el método OnStop solo se ejecuta DESPUÉS de que se completen todos los hilos.
¿Alguna pista de lo que se podría cambiar para solucionarlo?
Intenta poner Sleep (50) en el ciclo while. –
Me parece que usted no ha incluido la parte más importante del código. Esa es la implementación del método ProcessRequestList. –
¿Se puede mostrar el código donde se interroga a StopService? Busque utilizar CancellationToken sobre var estática, ya que está hecho para ese tipo de cosas. – hatchet