Mam aplikację wielowątkową, w której muszę anulować każde zadanie po określonym czasie, nawet jeśli w momencie anulowania używają zasobów niezarządzanych. Teraz używam następującego kodu (na przykład aplikacji konsoli). W prawdziwej aplikacji opóźnienie może wystąpić w zasobach niezarządzanych.Anuluj zadanie według czasu
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);
}
}
uzyskać wynik:
Ale nie jestem pewien, czy jest to dla rzeczywistej aplikacji z punktu widzenia bezpieczeństwa. użyłem również CancellationToken w różnych wariantach, ale to nie daje mi poprawny wynik, bo gdzie używam CancellAfter() lub .Delay() z przedziału czasu i anulować zadanie po ceratain razem mam następujące wyniki:
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);
}
}
W tej sytuacji wszystkie zadania muszą zostać anulowane, ponieważ Thread.Sleep()> czasu przydzielonego do wykonania każdego zadania. Ale widzimy, że niektóre czasy do wykonania.
Używam również następującą konstrukcję i daje ten sam wynik:
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);
}
}
Używam również równoległa i zainicjować anulacji Reklamowe Wewnątrz metody do() i używać Timer cancell żeton po horyzont czasowy, ale wszystkie dają ten sam rezultat.
SO, Dlaczego tak się dzieje i jaki jest właściwy sposób anulowania zadania po określonym czasie ???