У меня есть многопоточное приложение, где мне нужно отменить каждую задачу через определенное время, даже если во время отмены они используют неуправляемые ресурсы. Теперь я использую следующий код (например, консольное приложение). В реальном приложении задержка может возникать в неуправляемом ресурсе.Отменить задание по времени
static void Main()
{
for (int i = 0; i < 10; i++)
{
Task.Factory.StartNew(Do, TaskCreationOptions.LongRunning);
}
Console.ReadLine();
}
private static void Do()
{
new Timer(Thread.CurrentThread.Abort, null, 1000, -1);
try
{
Console.WriteLine("Start " + Task.CurrentId);
Thread.Sleep(2000);
Console.WriteLine("End " + Task.CurrentId);
}
catch (Exception)
{
Console.WriteLine("Thread Aborted " + Task.CurrentId);
}
}
Получить результат:
Но я не уверен, правильно ли это для реального приложения с точки зрения безопасности. Я также использовал CancellationToken в различных вариантах, но это не дает мне правильный результат, потому что, когда я использую CancellAfter() или .Delay() с временным интервалом и отменить задание после того, как ceratain времени я получил следующие результаты:
static void Main()
{
for (int i = 0; i < 10; i++)
{
var clt = new CancellationTokenSource();
Task task = new Task(() =>
{
Task.Delay(2000).ContinueWith(_ =>
{
clt.Cancel();
}, clt.Token);
Do(clt.Token);
}, clt.Token);
task.Start();
}
Console.ReadLine();
}
private static void Do(CancellationToken cltToken)
{
Console.WriteLine("Start " + Task.CurrentId);
Thread.Sleep(2500);
if (!cltToken.IsCancellationRequested)
{
Console.WriteLine("End " + Task.CurrentId);
}
else
{
Console.WriteLine("Cancelled "+ Task.CurrentId);
}
}
В этой ситуации все задачи должны быть отменены, так как Thread.Sleep()> времени, выделенного для выполнения каждой задачи. Но мы можем видеть, что некоторое время для выполнения.
Я также использую следующую конструкцию и дают тот же результат:
static void Main()
{
for (int i = 0; i < 10; i++)
{
var clt = new CancellationTokenSource();
clt.CancelAfter(2000);
Task.Factory.StartNew(Do, clt.Token);
}
Console.ReadLine();
}
private static void Do(object obj)
{
var cltToken = (CancellationToken) obj;
Console.WriteLine("Start " + Task.CurrentId);
Thread.Sleep(2500);
if (!cltToken.IsCancellationRequested)
{
Console.WriteLine("End " + Task.CurrentId);
}
else
{
Console.WriteLine("Cancelled "+ Task.CurrentId);
}
}
Я также использую Parallel и инициализировать отмены Токен Внутри метода Do(), и использовать таймер для cancell маркер после промежутка времени, но все дают тот же результат.
ТАК, Почему это происходит и каков правильный способ отменить задачу через определенное время ???