Im Vergleich zum vorherigen Code für die Klasse RulyCanceler wollte ich Code mit ausführen CancellationTokenSource
.
Wie verwende ich es wie in Stornierungs-Token erwähnt , dh ohne eine Ausnahme zu werfen / zu fangen? Kann ich die IsCancellationRequested
Immobilie nutzen?
Ich habe versucht, es so zu verwenden:
cancelToken.ThrowIfCancellationRequested();
und
try
{
new Thread(() => Work(cancelSource.Token)).Start();
}
catch (OperationCanceledException)
{
Console.WriteLine("Canceled!");
}
Dies führte jedoch zu einem Laufzeitfehler cancelToken.ThrowIfCancellationRequested();
in der Methode Work(CancellationToken cancelToken)
:
System.OperationCanceledException was unhandled
Message=The operation was canceled.
Source=mscorlib
StackTrace:
at System.Threading.CancellationToken.ThrowIfCancellationRequested()
at _7CancellationTokens.Token.Work(CancellationToken cancelToken) in C:\xxx\Token.cs:line 33
at _7CancellationTokens.Token.<>c__DisplayClass1.<Main>b__0() in C:\xxx\Token.cs:line 22
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
Der Code, den ich erfolgreich ausgeführt habe, hat die OperationCanceledException im neuen Thread abgefangen:
using System;
using System.Threading;
namespace _7CancellationTokens
{
internal class Token
{
private static void Main()
{
var cancelSource = new CancellationTokenSource();
new Thread(() =>
{
try
{
Work(cancelSource.Token); //).Start();
}
catch (OperationCanceledException)
{
Console.WriteLine("Canceled!");
}
}).Start();
Thread.Sleep(1000);
cancelSource.Cancel(); // Safely cancel worker.
Console.ReadLine();
}
private static void Work(CancellationToken cancelToken)
{
while (true)
{
Console.Write("345");
cancelToken.ThrowIfCancellationRequested();
}
}
}
}
CancellationTokenSource
mit asynchronen Methoden, lang laufenden Methoden mit Abfragen und die Verwendung eines Rückrufs.Antworten:
Sie können Ihre Arbeitsmethode wie folgt implementieren:
Das ist es. Sie müssen die Stornierung immer selbst vornehmen - beenden Sie die Methode, wenn es angemessen ist, sie zu beenden (damit Ihre Arbeit und Ihre Daten in einem konsistenten Zustand sind).
UPDATE: Ich schreibe lieber nicht,
while (!cancelToken.IsCancellationRequested)
da es oft nur wenige Exit-Punkte gibt, an denen Sie die sichere Ausführung über den Loop-Body hinweg beenden können, und Loop normalerweise eine logische Bedingung zum Beenden hat (Iteration über alle Elemente in der Sammlung usw.). Ich glaube, es ist besser, diese Bedingungen nicht zu mischen, da sie unterschiedliche Absichten haben.Warnhinweis zur Vermeidung
CancellationToken.ThrowIfCancellationRequested()
:Kommentar von Eamon Nerbonne :
quelle
@ BrainSlugs83
Sie sollten nicht blindlings auf alles vertrauen, was im Stackoverflow veröffentlicht wurde. Der Kommentar im Jens-Code ist falsch. Der Parameter steuert nicht, ob Ausnahmen ausgelöst werden oder nicht.
MSDN ist sehr klar, was dieser Parameter steuert. Haben Sie es gelesen? http://msdn.microsoft.com/en-us/library/dd321703(v=vs.110).aspx
Der Variablenname ist auch falsch, da Abbrechen
CancellationTokenSource
nicht für das Token selbst aufgerufen wird und die Quelle den Status jedes von ihr verwalteten Tokens ändert.quelle
Sie können eine Aufgabe mit einem Stornierungs-Token erstellen. Wenn Sie zum Hintergrund der App wechseln, können Sie dieses Token abbrechen.
Sie können dies in PCL https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/app-lifecycle tun
Eine weitere Lösung ist der Benutzer-Timer in Xamarin.Forms. Stoppen Sie den Timer, wenn die App zum Hintergrund wechselt. Https://xamarinhelp.com/xamarin-forms-timer/
quelle
Sie können verwenden,
ThrowIfCancellationRequested
ohne die Ausnahme zu behandeln!Die Verwendung von
ThrowIfCancellationRequested
soll innerhalb von aTask
(nicht aThread
) verwendet werden. Bei Verwendung innerhalb von aTask
müssen Sie die Ausnahme nicht selbst behandeln (und erhalten den Fehler "Nicht behandelte Ausnahme"). Dies führt dazu, dassTask
dieTask.IsCancelled
Eigenschaft verlassen wird und die Eigenschaft True ist. Keine Ausnahmebehandlung erforderlich.Ändern Sie in Ihrem speziellen Fall das
Thread
in aTask
.quelle
t.Start()
und nichtTask.Run()
?Sie müssen das
CancellationToken
an die Aufgabe übergeben, die das Token regelmäßig überwacht, um festzustellen, ob eine Stornierung angefordert wird.In diesem Fall endet die Operation , wenn Annullierung angefordert wird und die
Task
einen habenRanToCompletion
Zustand. Wenn Sie bestätigt werden möchten, dass Ihre Aufgabe abgebrochen wurde , müssen SieThrowIfCancellationRequested
eineOperationCanceledException
Ausnahme auslösen.Hoffe das hilft besser zu verstehen.
quelle