C# 如何正确重置CancellationToken?

C# 如何正确重置CancellationToken?,c#,asynchronous,async-await,cancellationtokensource,cancellation-token,C#,Asynchronous,Async Await,Cancellationtokensource,Cancellation Token,今天早上我一直在玩异步CTP,有一个带有按钮和标签的简单程序。单击按钮,它开始更新标签,停止按钮它停止写入标签。但是,我不确定如何重置CancellationTokenSource,以便重新启动进程 我的代码: public partial class MainWindow : Window { CancellationTokenSource cts = new CancellationTokenSource(); public MainWindow() {

今天早上我一直在玩
异步CTP
,有一个带有
按钮和
标签的简单程序。单击
按钮
,它开始更新
标签
,停止
按钮
它停止写入
标签
。但是,我不确定如何重置
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();
        }
    }
}

您需要重新创建
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();
    }
}

我也遇到了同样的问题,我发现解决这个问题的最好方法是在调用方法之前新建一个取消令牌源

这是我在“开始”按钮上执行的操作单击:

cancellationTokenSource = new CancellationTokenSource();
cancellationToken = cancellationTokenSource.Token;
Task.Factory.StartNew(StartUpload, cancellationToken);
我将同一按钮的标题更改为cancel,当单击cancel时,我调用

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

您应该在应用程序关闭时何时处理它?由于在线程完成之前必须等待,否则会出现ObjectDisposed异常。@user2587718这实际上取决于对象的类型,等等。我建议你问自己关于这个的问题。在处理之前真的应该做一个空检查,但这很好,因为这正是我正在做的。试图了解更多关于CancellationTokens的信息,为什么你不在
Cancel
调用后立即处理cts?它是否应该在下一次更新时才被处理掉?