如何重置CancellationTokenSource并使用VS2010调试多线程?

q09*_*987 21 .net c# debugging winforms cancellationtokensource

我使用CancellationTokenSource来提供一个函数,以便用户可以取消冗长的操作.但是,在用户应用第一次取消后,后面的进一步操作不再起作用.我的猜测是CancellationTokenSource的状态已设置为Cancel,我想知道如何重置它.

  • 问题1:如何在首次使用后重置CancellationTokenSource?

  • 问题2:如何在VS2010中调试多线程?如果我在调试模式下运行应用程序,我可以看到该语句的以下异常

    this.Text = string.Format("Processing {0} on thread {1}", filename, Thread.CurrentThread.ManagedThreadId);
    
    Run Code Online (Sandbox Code Playgroud)

用户代码未处理InvalidOperaationException跨线程操作无效:控制从其创建的线程以外的线程访问的"MainForm".

谢谢.

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();
}
Run Code Online (Sandbox Code Playgroud)

Cod*_*aos 34

问题1>如何在首次使用后重置CancellationTokenSource?

如果您取消它,它将被取消,无法恢复.你需要一个新的CancellationTokenSource.A CancellationTokenSource不是某种工厂.它只是单个令牌的所有者.它应该被称为IMO CancellationTokenOwner.

问题2>如何在VS2010中调试多线程?如果我在调试模式下运行应用程序,我可以看到该语句的以下异常

这与调试无关.您无法从另一个线程访问gui控件.你需要使用Invoke它.我猜你只在调试模式下看到问题,因为在发布模式下禁用了一些检查.但是这个bug仍然存在.

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