Par rapport au code précédent pour la classe RulyCanceler , je voulais exécuter du code en utilisant CancellationTokenSource
.
Comment puis-je l'utiliser comme mentionné dans les jetons d'annulation , c'est-à-dire sans lancer / attraper une exception? Puis-je utiliser la IsCancellationRequested
propriété?
J'ai essayé de l'utiliser comme ceci:
cancelToken.ThrowIfCancellationRequested();
et
try
{
new Thread(() => Work(cancelSource.Token)).Start();
}
catch (OperationCanceledException)
{
Console.WriteLine("Canceled!");
}
mais cela a donné une erreur d'exécution sur la cancelToken.ThrowIfCancellationRequested();
méthode 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:
Le code que j'ai exécuté avec succès a attrapé l'exception OperationCanceledException dans le nouveau thread:
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
avec des méthodes asynchrones, des méthodes de longue durée avec interrogation et l'utilisation d'un rappel.Réponses:
Vous pouvez implémenter votre méthode de travail comme suit:
C'est tout. Vous devez toujours gérer l'annulation par vous-même - quitter la méthode au moment opportun pour quitter (afin que votre travail et vos données soient dans un état cohérent)
MISE À JOUR: Je préfère ne pas écrire
while (!cancelToken.IsCancellationRequested)
car il y a souvent peu de points de sortie où vous pouvez arrêter de s'exécuter en toute sécurité sur le corps de la boucle, et la boucle a généralement une condition logique pour quitter (itérer sur tous les éléments de la collection, etc.). Je pense donc qu'il vaut mieux ne pas mélanger ces conditions car elles ont une intention différente.Attention à éviter
CancellationToken.ThrowIfCancellationRequested()
:Commentaire en question par Eamon Nerbonne :
la source
@ BrainSlugs83
Vous ne devriez pas faire confiance aveuglément à tout ce qui est publié sur stackoverflow. Le commentaire dans le code Jens est incorrect, le paramètre ne contrôle pas si les exceptions sont levées ou non.
MSDN est très clair ce que contrôle ce paramètre, l'avez-vous lu? http://msdn.microsoft.com/en-us/library/dd321703(v=vs.110).aspx
Le nom de la variable est également erroné car Cancel n'est pas appelé sur
CancellationTokenSource
le jeton lui-même et la source change l'état de chaque jeton qu'elle gère.la source
Vous pouvez créer une tâche avec un jeton d'annulation, lorsque vous passez en arrière-plan, vous pouvez annuler ce jeton.
Vous pouvez le faire dans PCL https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/app-lifecycle
Une autre solution est le minuteur utilisateur dans Xamarin.Forms, arrêtez le minuteur lorsque l'application est en arrière-plan https://xamarinhelp.com/xamarin-forms-timer/
la source
Vous pouvez utiliser
ThrowIfCancellationRequested
sans gérer l'exception!L'utilisation de
ThrowIfCancellationRequested
est destinée à être utilisée à partir d'unTask
(et non d'unThread
). Lorsqu'il est utilisé dans aTask
, vous ne devez pas gérer l'exception vous-même (et obtenir l'erreur Exception non gérée). Cela entraînera la sortie deTask
, et laTask.IsCancelled
propriété sera True. Aucune gestion d'exception requise.Dans votre cas spécifique, remplacez le
Thread
par unTask
.la source
t.Start()
et nonTask.Run()
?Vous devez transmettre le
CancellationToken
à la tâche, qui surveillera périodiquement le jeton pour voir si l'annulation est demandée.Dans ce cas, l'opération se terminera lorsque l'annulation sera demandée et le
Task
aura unRanToCompletion
état. Si vous voulez être reconnu que votre tâche a été annulée , vous devez utiliserThrowIfCancellationRequested
pour lever uneOperationCanceledException
exception.J'espère que cela aide à mieux comprendre.
la source