web-dev-qa-db-fra.com

Comment réinitialiser correctement un CancellationToken?

J'ai joué avec les Async CTP ce matin et ayez un programme simple avec un button et un label. Cliquez sur le button et il commence à mettre à jour le label, arrêtez le button il arrête d'écrire dans le label. Cependant, je ne sais pas comment réinitialiser le CancellationTokenSource pour pouvoir redémarrer le processus.

Mon code:

public partial class MainWindow : Window
{
    CancellationTokenSource cts = new CancellationTokenSource();
    public MainWindow()
    {
        InitializeComponent();
        button.Content = "Start";
    }

    async Task DoWork(CancellationToken cancelToken)
    {
        int i = 0;
        while (!cancelToken.IsCancellationRequested)
        {
            label.Content = i++.ToString();
            await TaskEx.Delay(50, cancelToken);
        }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (button.Content == "Start")
        {
            button.Content = "Stop";
            DoWork(cts.Token);
        }
        else
        {
            button.Content = "Start";
            cts.Cancel();
        }
    }
}
48
poco

Vous devez recréer le CancellationTokenSource - il n'y a aucun moyen de "réinitialiser" ceci une fois que vous l'avez défini.

Cela pourrait être aussi simple que:

private void Button_Click(object sender, RoutedEventArgs e)
{
    if (button.Content == "Start")
    {
        button.Content = "Stop";
        cts.Dispose(); // Clean up old token source....
        cts = new CancellationTokenSource(); // "Reset" the cancellation token source...
        DoWork(cts.Token);
    }
    else
    {
        button.Content = "Start";
        cts.Cancel();
    }
}
66
Reed Copsey

Même j'ai eu le même problème et je l'ai compris, la meilleure façon de le résoudre est de créer une source de jeton d'annulation juste avant d'appeler la méthode.

voici ce que je fais sur mon bouton de démarrage:

cancellationTokenSource = new CancellationTokenSource();
cancellationToken = cancellationTokenSource.Token;
Task.Factory.StartNew(StartUpload, cancellationToken);

Je modifie la légende du même bouton pour annuler et lorsqu'un clic se produit sur annuler, j'appelle

cancellationTokenSource.Cancel();

Voici le code complet:

if (button3.Text != "&Start Upload")
        {
            cancellationTokenSource.Cancel();
        }
        else
        {
            try
            {
                cancellationTokenSource = new CancellationTokenSource();
                cancellationToken = cancellationTokenSource.Token;
                Task.Factory.StartNew(StartUpload, cancellationToken);
            }
            catch (AggregateException ex)
            {
                var builder = new StringBuilder();
                foreach (var v in ex.InnerExceptions)
                    builder.Append("\r\n" + v.InnerException);
                MessageBox.Show("There was an exception:\r\n" + builder.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
6
Amit