Mi pregunta es ¿cómo puedo detener una tarea de ejecución larga (.net 4)? Implementé TPL e intenté usar CancellationTokenSource, pero parece que no funciona para mi escenario. Todos los ejemplos que he visto suponen que está trabajando en un ciclo while para que pueda verificar si la tarea se ha cancelado, mientras que solo tengo una operación única que requiere mucho tiempo. No puedo esperar a que se complete el trabajo, ya que necesito suponer que nunca se completará. Este es el código que he intentado:Detener con seguridad la tarea de larga ejecución
bool? result = null;
var cs = new CancellationTokenSource();
var ct = cs.Token;
var doWorkTask = new Task(() =>
{
Console.WriteLine("start dowork task");
result = Work.LongRunning();
}, ct);
doWorkTask.Start();
Task.WaitAny(new Task[] { doWorkTask }, timetowait);
if (doWorkTask.IsCompleted)
{
Console.WriteLine("dowork task completed");
doWorkTask.Dispose();
}
else
{
Console.WriteLine("dowork task has timedout");
cs.Cancel();
throw new TimeoutException("Timeout hit.");
}
El código funciona, pero la tarea no está dispuesto si el “tiempo de espera” ocurre y el trabajo que se está realizando accesos “código no administrado” es decir los recursos. Dicho esto, el IsCancelledRequested no se puede usar en Work.LongRunning() así que no puedo ThrowIfCancellationRequested.
Estoy abierto a otras ideas, así como también lo he probado en BackgroundWorker, pero eso tampoco parece encajar.
Nueva ejemplo:
var service = new System.ServiceProcess.ServiceController(ServiceName, ServerName);
var serviceTask = Task.Factory.StartNew(() =>
{
result = (service.Status == ServiceControllerStatus.Running
|| service.Status == ServiceControllerStatus.StartPending);
}, cs.Token);
serviceTask.Wait(2000, cs.Token);
if (!serviceTask.IsCompleted)
{
cs.Cancel();
}
Gracias por la respuesta! Miré el patrón Begin \ End, pero luego verifiqué un resultado en End's ((Task) isyncResult). Result que tienes que esperar hasta que finalice. Hice una actualización de mi ejemplo. Como las propiedades del ServiceController parecen estar cargadas de forma perezosa en cuanto compruebas un valor, puede que tarde un tiempo ... –
nickv
Debo admitir que no puedo seguir tu código por completo, pero ¿por qué no agregas continuaciones con ContinueWith? ? – Stilgar
Porque no quiero continuar con una nueva tarea. Tengo una tarea que deseo realizar, esa tarea puede no generar una respuesta debido a lo que sea que la tarea estará en estado de ejecución para siempre, aunque se haya llamado a Cancelado. – nickv