У меня есть несколько задач для выполнения. Каждая задача завершает свое выполнение в разное время. Некоторые из задач выполняют доступ к базе данных, некоторые из них просто делают некоторые вычисления. Мой код имеет следующую структуру:Задачи C# не отменены
var Canceller = new CancellationTokenSource();
List<Task<int>> tasks = new List<Task<int>>();
tasks.Add(new Task<int>(() => { Thread.Sleep(3000); Console.WriteLine("{0}: {1}", DateTime.Now, 3); return 3; }, Canceller.Token));
tasks.Add(new Task<int>(() => { Thread.Sleep(1000); Console.WriteLine("{0}: {1}", DateTime.Now, 1); return 1; }, Canceller.Token));
tasks.Add(new Task<int>(() => { Thread.Sleep(2000); Console.WriteLine("{0}: {1}", DateTime.Now, 2); return 2; }, Canceller.Token));
tasks.Add(new Task<int>(() => { Thread.Sleep(8000); Console.WriteLine("{0}: {1}", DateTime.Now, 8); return 8; }, Canceller.Token));
tasks.Add(new Task<int>(() => { Thread.Sleep(6000); Console.WriteLine("{0}: {1}", DateTime.Now, 6); return 6; }, Canceller.Token));
tasks.ForEach(x => x.Start());
bool Result = Task.WaitAll(tasks.Select(x => x).ToArray(), 3000);
Console.WriteLine(Result);
Canceller.Cancel();
tasks.ToList().ForEach(x => { x.Dispose(); }); // Exception here
tasks.Clear();
tasks = null;
Canceller.Dispose();
Canceller = null;
У меня есть период в 5 секунд, чтобы начать все эти задачи. Через каждые 5 секунд я вызываю код выше. Перед следующим вызовом я должен быть уверен, что никаких задач не осталось из предыдущего периода выполнения. Предположим, что после выполнения выполнения 3 секунды я хотел бы отменить выполнение задач, которые не были выполнены.
При запуске кода Task.WaitAll
параметр 3000 позволяет сначала выполнить 3 задачи, как ожидалось. Затем я получаю Result
как false
, потому что еще 2 задания не завершены. Затем я должен отменить эти две задачи. Если я попытаюсь их уничтожить, я получаю исключение: «Задачи в завершенном состоянии могут быть удалены».
Как я могу это достичь? После того, как я вызываю Cancel
метод CancellationTokenSource
, эти две задачи все еще выполняются. Что здесь не так?
Разделить работу ('Sleep (8000)') в части ('Sleep (100) * 80') и проверка для ['IsCancelationRequest'] (https://msdn.microsoft.com/en-us/library/dd997396 (v = vs.110) .aspx) перед началом каждой части. – Sinatr