如何重置CancellationTokenSource和调试VS2010的多线程? [英] How to reset the CancellationTokenSource and debug the multithread with VS2010?

查看:277
本文介绍了如何重置CancellationTokenSource和调试VS2010的多线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经使用CancellationTokenSource提供一个功能,使得用户可以 取消冗长的行动。然而,用户施加后第一取消, 后来进一步的行动不再工作了。我的猜测是,CancellationTokenSource的状态已被设置为取消,我想知道如何重置 它回来了。

  • 问题1:如何在第一时间使用后重置CancellationTokenSource

  • 问题2:如何调试在VS2010的多线程? 如果我在调试模式下运行应用程序,我可以看到下面的例外 声明

      this.Text =的String.Format(处理{0}在线程{1},文件名,Thread.CurrentThread.ManagedThreadId);
     

  

InvalidOperaationException是未处理由用户code   跨线程操作无效:控制'的MainForm'从一个线程访问其它   比它的线程上创建。

感谢你。

 私人CancellationTokenSource cancelToken =新CancellationTokenSource();

私人无效的button1_Click(对象发件人,EventArgs的)
{
    Task.Factory.StartNew(()=>
    {
        ProcessFilesThree();
    });
}

私人无效ProcessFilesThree()
{
    ParallelOptions parOpts =新ParallelOptions();
    parOpts.CancellationToken = cancelToken.Token;
    parOpts.MaxDegreeOfParallelism = System.Environment.ProcessorCount;

    字符串[]文件= Directory.GetFiles(@C:\ TEMP \在,* .JPG,SearchOption.AllDirectories);
    字符串NEWDIR = @C:\ TEMP \出\;
    Directory.CreateDirectory(NEWDIR);

    尝试
    {
        Parallel.ForEach(文件,parOpts,(currentFile)=>
        {
            parOpts.CancellationToken.ThrowIfCancellationRequested();

            字符串文件名= Path.GetFileName(currentFile);

            使用(位图位图=新位图(currentFile))
            {
                bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone);
                bitmap.Save(Path.Combine(NEWDIR,文件名));
                this.Text = tring.Format(处理{0}在线程{1},文件名,Thread.CurrentThread.ManagedThreadId);
            }
        });

        this.Text =全部完成!;
    }
    赶上(OperationCanceledException前)
    {
        this.Text = ex.Message;
    }
}

私人无效button2_Click(对象发件人,EventArgs的)
{
    cancelToken.Cancel();
}
 

解决方案
  

问题1>如何在第一时间使用后重置CancellationTokenSource?

如果你取消,那么它取消,并无法恢复。你需要一个新的 CancellationTokenSource 。 A CancellationTokenSource 是不是有些类型的工厂。这是一个令牌就是老板。国际海事组织它应该被称为 CancellationTokenOwner

  

问2>如何调试在VS2010的多线程?如果我在调试模式下运行应用程序,我可以看到下面的例外的声明

这无关调试。您不能访问从另一个线程的GUI控制。你需要使用调用为。我猜你看到的问题只是在调试模式,因为有些检查是在释放模式禁用。但错误依然存在。

  Parallel.ForEach(文件,parOpts,(currentFile)=>
{
  ...
  this.Text = ...; //<  - 此分配是非法的
  ...
});
 

I have used CancellationTokenSource to provide a function so that the user can cancel the lengthy action. However, after the user applies the first cancellation, the later further action doesn't work anymore. My guess is that the status of CancellationTokenSource has been set to Cancel and I want to know how to reset it back.

  • Question 1: How to reset the CancellationTokenSource after the first time usage?

  • Question 2: How to debug the multithread in VS2010? If I run the application in debug mode, I can see the following exception for the statement

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

InvalidOperaationException was unhandled by user code Cross-thread operation not valid: Control 'MainForm' accessed from a thread other than the thread it was created on.

Thank you.

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

解决方案

Question 1> How to reset the CancellationTokenSource after the first time usage?

If you cancel it, then it's cancelled and can't be restored. You need a new CancellationTokenSource. A CancellationTokenSource isn't some kind of factory. It's just the owner of a single token. IMO it should have been called CancellationTokenOwner.

Question 2> How to debug the multithread in VS2010? If I run the application in debug mode, I can see the following exception for the statement

That has nothing to do with debugging. You can't access a gui control from another thread. You need to use Invoke for that. I guess you see the problem only in debug mode because some checks are disabled in release mode. But the bug is still there.

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

这篇关于如何重置CancellationTokenSource和调试VS2010的多线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆