Frage

Ich habe heute Morgen mit dem async ctp herumgespielt und habe ein einfaches Programm mit einem button und einem label.Klicken Sie auf den button und der label wird aktualisiert. Stoppen Sie den button, der nicht mehr in den label geschrieben wird.Ich bin mir jedoch nicht sicher, wie ich den CancellationTokenSource zurücksetzen soll, damit ich den Prozess neu starten kann.Mein Code ist unten:

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();
        }
    }
}

War es hilfreich?

Lösung

Sie müssen den CancellationTokenSource neu erstellen - es gibt keine Möglichkeit, diesen nach dem Festlegen zurückzusetzen.

Dies kann so einfach sein wie:

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();
    }
}

Andere Tipps

Sogar ich hatte das gleiche Problem und habe herausgefunden, dass der beste Weg, es zu lösen, darin besteht, eine Quelle für das Lösch-Token kurz vor dem Aufruf der Methode neu zu erstellen.

Dies ist, was ich mache, wenn ich auf die Schaltfläche "Start" klicke:

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

Ich ändere die Beschriftung für dieselbe Schaltfläche, um abzubrechen, und wenn ein Klick auf Abbrechen auftritt, rufe ich an

cancellationTokenSource.Cancel();

Hier ist der vollständige Code:

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);
            }
        }

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top