69

Async CTP私は今朝 で遊んでいて、buttonとを使った簡単なプログラムを持っていlabelます。をクリックするbuttonと の更新が始まりlabel、 を停止するbuttonと への書き込みが停止しlabelます。CancellationTokenSourceただし、プロセスを再開できるようにリセットする方法がわかりません。

私のコード:

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

3 に答える 3

99

を再作成する必要がありCancellationTokenSourceます。一度設定すると、これを「リセット」する方法はありません。

これは次のように簡単です。

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();
    }
}
于 2012-02-17T17:17:44.373 に答える
9

私は同じ問題を抱えていましたが、それを解決する最善の方法は、メソッドを呼び出す直前にキャンセル トークン ソースを新しく作成することであることがわかりました。

これは、スタートボタンのクリックで私が行うことです:

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

同じボタンのキャプションをキャンセルに変更し、キャンセル時にクリックが発生したときに呼び出します

cancellationTokenSource.Cancel();

完全なコードは次のとおりです。

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);
    }
}
于 2013-12-04T07:05:31.323 に答える