我已经使用 CancellationTokenSource 提供了一个函数,这样用户就可以 取消冗长的 Action 。但是,在用户申请第一次取消后, 后来的进一步行动不再有效。我的猜测是 CancellationTokenSource 的状态已经设置为 Cancel 我想知道如何重置 它回来了。
问题一:第一次使用后如何重置CancellationTokenSource?
问题2:如何在VS2010中调试多线程? 如果我在 Debug模式下运行应用程序,我可以看到以下异常 声明
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.
谢谢。
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?
如果您取消它,它就会被取消并且无法恢复。您需要一个新的 CancellationTokenSource
。 CancellationTokenSource
不是某种工厂。它只是一个 token 的所有者。在我看来,它应该被称为 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
这与调试无关。您不能从另一个线程访问 gui 控件。为此,您需要使用 Invoke
。我猜您只在 Debug模式下看到问题,因为某些检查在 Release模式下被禁用。但是错误仍然存在。
Parallel.ForEach(files, parOpts, (currentFile) =>
{
...
this.Text = ...;// <- this assignment is illegal
...
});
关于c# - 如何重置 CancellationTokenSource 并使用 VS2010 调试多线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6168483/