J'ai un code qui crée un jeton d'annulation
public partial class CardsTabViewModel : BaseViewModel
{
public CancellationTokenSource cts;
public async Task OnAppearing()
{
cts = new CancellationTokenSource(); // << runs as part of OnAppearing()
Code qui l'utilise:
await GetCards(cts.Token);
public async Task GetCards(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
App.viewablePhrases = App.DB.GetViewablePhrases(Settings.Mode, Settings.Pts);
await CheckAvailability();
}
}
et le code qui annule ultérieurement ce jeton d'annulation si l'utilisateur s'éloigne de l'écran sur lequel le code ci-dessus s'exécute:
public void OnDisappearing()
{
cts.Cancel();
En ce qui concerne l'annulation, est-ce la bonne façon d'annuler le jeton lorsqu'il est utilisé dans une tâche?
En particulier, j'ai vérifié cette question:
Utilisation de la propriété IsCancellationRequested?
et cela me fait penser que je ne fais pas l'annulation de la bonne façon ou peut-être d'une manière qui peut provoquer une exception.
De plus, dans ce cas après avoir annulé, dois-je faire un cts.Dispose ()?
c#
xamarin
xamarin.forms
Alan2
la source
la source
Réponses:
CancellationTokenSource.Cancel()
est un moyen valide pour commencer l'annulation.Le vote
ct.IsCancellationRequested
évite de lancerOperationCanceledException
. Du fait de son interrogation, il nécessite une itération de la boucle pour se terminer avant de répondre à la demande d'annulation.Si
GetViewablePhrases()
etCheckAvailability()
peut être modifié pour accepter unCancellationToken
, cela peut accélérer l'annulation de la réponse, au prix d'avoirOperationCanceledException
jeté."devrais-je faire un cts.Dispose ()?" n'est pas si simple ...
Est plus une ligne directrice qu'une règle.
Task
lui-même est jetable, mais presque jamais directement disposé dans le code.Il y a des cas (lorsque
WaitHandle
ou des gestionnaires de rappel d'annulation sont utilisés) où la suppressioncts
libérerait une ressource / supprimerait une racine GC qui ne serait autrement libérée que par un Finalizer. Ceux-ci ne s'appliquent pas à votre code tel qu'il est, mais pourraient le devenir à l'avenir.L'ajout d'un appel à
Dispose
après l'annulation garantirait que ces ressources sont libérées rapidement dans les futures versions du code.Cependant, vous devez soit attendre la fin du code qui utilise
cts
avant d'appeler dispose, soit modifier le code à gérer àObjectDisposedException
partir de l'utilisation dects
(ou de son jeton) après la suppression.la source
CancellationToken
paramètre), vous pourriez êtreWaitHandle
en train de supprimer le pendant qu'un autre thread l'attend activement :(Dispose
depuisOnDisappearing
.Cancel
...Cancel
est le minuteur interne (s'il est utilisé).En général, je vois une utilisation équitable du jeton d'annulation dans votre code, mais selon le modèle de tâche asynchrone, votre code pourrait ne pas annuler immédiatement.
Pour répondre immédiatement, le code de blocage doit également être annulé
C'est à vous si vous devez vous débarrasser, s'il y a beaucoup de ressources mémoire réservées dans le code interrompu, vous devez le faire.
la source
Je vous recommanderais de jeter un oeil sur l'une des classes .net pour bien comprendre comment gérer les méthodes d'attente avec CanncelationToken, j'ai choisi SeamaphoreSlim.cs
Vous pouvez également afficher la classe entière ici, https://referencesource.microsoft.com/#mscorlib/system/threading/SemaphoreSlim.cs,6095d9030263f169
la source