Безопасно остановить длительную задачу

Мой вопрос в том, как я могу остановить длительную задачу (.net 4 )? Я внедрил TPL и попытался использовать CancellationTokenSource, но, похоже, это не работает для моего сценария. Во всех примерах, которые я видел, предполагается, что вы выполняете работу в цикле while -, чтобы вы могли проверить, была ли задача отменена, тогда как у меня есть только одна операция, которая занимает много времени. Я не могу дождаться завершения работы, так как должен предположить, что она никогда не будет завершена. Вот код, который я пробовал:

        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.");
        }

Код работает, но задача никогда не удаляется, если происходит «тайм-аут», и выполняемая работа обращается к «неуправляемому коду», то есть к ресурсам.При этом IsCancelledRequested нельзя использовать в Work.LongRunning (), поэтому я не могу использовать ThrowIfCancellationRequested.

Я открыт для других идей, а также пробовал BackgroundWorker, но это тоже не подходит.

Новый пример:

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();
        }
11
задан nickv 2 May 2012 в 14:09
поделиться