我有两个按钮,点击开始按钮会创建一个线程执行一个方法,方法运行一段时间,在结束前会修改界面上的值。
点击取消按钮会调用CancelTokenSource.Cancel();来取消线程。现在出现的问题是,我点击开始-停止-开始后,CancelTokenSource被重置了,第一个本来该取消的线程,读信号时认为不会取消,就又会改变界面上的值,导致错误的结果。请问怎么能记住这个线程被取消过呢?简化的过程代码如下:
public CancellationTokenSource CancelTokenSource;bool isCancel;
private void buttonStart_Click(object sender, EventArgs e)
{
    isCancel = false;
    CancelTokenSource = new CancellationTokenSource();
    Task task = Task.Factory.StartNew(() =>
        {
            Console.WriteLine($"id={Thread.CurrentThread.ManagedThreadId} 启动了一个线程  
            IsCancellationRequested={CancelTokenSource.IsCancellationRequested} isCancel={isCancel}");            Thread.Sleep(10000);            Console.WriteLine($"id={Thread.CurrentThread.ManagedThreadId} 10s后看状态 
            IsCancellationRequested={CancelTokenSource.IsCancellationRequested} isCancel={isCancel}");        }, CancelTokenSource.Token);
}private void buttonCancel_Click(object sender, EventArgs e)
{
    CancelTokenSource.Cancel();    isCancel = true;
}
我点击开始-取消-开始。 创建一个线程后,取消线程,再创建一个线程。结果显示第一个线程的取消状态被重置了。
id=10 启动了一个线程  IsCancellationRequested=False isCancel=False
id=11 启动了一个线程  IsCancellationRequested=False isCancel=False
id=10 10s后看状态 IsCancellationRequested=False isCancel=False  //想要的结果是true
id=11 10s后看状态 IsCancellationRequested=False isCancel=False

解决方案 »

  1.   

    不是被你自己重新new了一个吗?
      

  2.   

    多谢回复,我之前以为new CancellationTokenSource()传给两个线程,就是两个不同的标记...
    线程一调用cts.Cancel后,再new cts传给二不会影响到线程一,这样线程一在结束前还能知道它被Cancel过...测试发现好像还是同一个已解决,代码如下
    private void buttonStart(object sender, EventArgs e)
    {
        cts = new CancellationTokenSource();    Task task = Task.Factory.StartNew(() =>        
            {
                bool isCancel = false;
                cts.Token.Register(() => isCancel = true);            Console.WriteLine($"启动了一个线程 id={Thread.CurrentThread.ManagedThreadId} cts={cts.IsCancellationRequested}  isCancel={isCancel}");            Thread.Sleep(10000);            Console.WriteLine($"10s后查看状态 id={Thread.CurrentThread.ManagedThreadId} cts={cts.IsCancellationRequested }  isCancel={isCancel}");
            }
            , cts.Token);
    }
    打印结果如下:
    启动了一个线程 id=12 cts=False  isCancel=False
    启动了一个线程 id=13 cts=False  isCancel=False
    10s后查看状态 id=12 cts=False  isCancel=True
    10s后查看状态 id=13 cts=False  isCancel=False
      

  3.   

    获取CancellationTokenSource 的IsCancellationRequested属性即可,不需要自己定义变量。
      

  4.   

    大哥,我在1楼底部把结果都打印出来了,我取消了,这个属性还是false
      

  5.   

    大哥,我在1楼底部把结果都打印出来了,我取消了,这个属性还是false
    很明显不能在startNew中获取是否取消标识。toke通知任务取消,内部再怎么获取也是false。