Ich habe eine Multithread-Anwendung, bei der ich jede Aufgabe nach einer bestimmten Zeit abbrechen muss, selbst wenn sie zum Zeitpunkt der Stornierung nicht verwaltete Ressourcen verwendet. Jetzt verwende ich den folgenden Code (z. B. eine Konsolenanwendung). In einer realen Anwendung kann die Verzögerung in der nicht verwalteten Ressource auftreten.Aufgabe nach Zeit abbrechen
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);
}
}
Holen Sie sich das Ergebnis:
Aber ich bin mir nicht sicher, ob es sich für eine echte Anwendung aus der Sicht der Sicherheit richtig ist. habe ich auch CancellationToken in verschiedenen Varianten, aber es mir nicht korrektes Ergebnis geben, da, wo ich CancellAfter() oder .Delay() mit dem Zeitraum und storniert Aufgabe nach ceratain Zeit bekam ich folgende Ergebnisse:
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);
}
}
In dieser Situation müssen alle Aufgaben abgebrochen werden, da Thread.Sleep()> der Zeit zugewiesen ist, um jede Aufgabe auszuführen. Aber wir können sehen, dass ein Teil der Zeit ausgeführt wird.
ich auch folgende Konstruktion verwenden und das gleiche Ergebnis:
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);
}
}
ich auch parallel nutzen und Stornierungs Token Innerhalb Methode Do() initialisieren, und verwenden Sie Timer nach Zeitspanne Token absagen, aber alle geben das gleiche Ergebnis.
SO, warum ist das passiert und was ist der richtige Weg, um die Aufgabe nach einer bestimmten Zeit abzubrechen ???