CancellationTokenSource

CancellationTokenSource

我已经使用CancellationTokenSource提供了一个功能,以便用户可以
取消冗长的 Action 。但是,在用户应用首次取消后,
以后的进一步操作将不再起作用。我的猜测是CancellationTokenSource的状态已设置为Cancel,我想知道如何重置
回来了。

  • 问题1:首次使用后如何重置CancellationTokenSource?
  • 问题2:如何在VS2010中调试多线程?
    如果以 Debug模式运行该应用程序,则可以看到以下异常
    该声明
    this.Text = string.Format("Processing {0} on thread {1}", filename, Thread.CurrentThread.ManagedThreadId);
    



  • 谢谢。
    private CancellationTokenSource cancelToken = new CancellationTokenSource();
    
    private void button1_Click(object sender, EventArgs e)
    {
        Task.Factory.StartNew( () =>
        {
            ProcessFilesThree();
        });
    }
    
    private void ProcessFilesThree()
    {
        ParallelOptions parOpts = new ParallelOptions();
        parOpts.CancellationToken = cancelToken.Token;
        parOpts.MaxDegreeOfParallelism = System.Environment.ProcessorCount;
    
        string[] files = Directory.GetFiles(@"C:\temp\In", "*.jpg", SearchOption.AllDirectories);
        string newDir = @"C:\temp\Out\";
        Directory.CreateDirectory(newDir);
    
        try
        {
            Parallel.ForEach(files, parOpts, (currentFile) =>
            {
                parOpts.CancellationToken.ThrowIfCancellationRequested();
    
                string filename = Path.GetFileName(currentFile);
    
                using (Bitmap bitmap = new Bitmap(currentFile))
                {
                    bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
                    bitmap.Save(Path.Combine(newDir, filename));
                    this.Text =  tring.Format("Processing {0} on thread {1}",  filename, Thread.CurrentThread.ManagedThreadId);
                }
            });
    
            this.Text = "All done!";
        }
        catch (OperationCanceledException ex)
        {
            this.Text = ex.Message;
        }
    }
    
    private void button2_Click(object sender, EventArgs e)
    {
        cancelToken.Cancel();
    }
    

    最佳答案



    如果您取消它,则它被取消并且无法还原。您需要一个新的CancellationTokenSourceCancellationTokenSource不是某种工厂。它只是单个 token 的所有者。 IMO,它应该被称为CancellationTokenOwner



    这与调试无关。您不能从另一个线程访问gui控件。您需要为此使用Invoke。我猜您只能在 Debug模式下看到问题,因为在 Release模式下禁用了某些检查。但是错误仍然存​​在。

    Parallel.ForEach(files, parOpts, (currentFile) =>
    {
      ...
      this.Text =  ...;// <- this assignment is illegal
      ...
    });
    

    10-04 11:40