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 statementthis.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();
}
If you cancel it, then it’s cancelled and can’t be restored. You need a new
CancellationTokenSource. ACancellationTokenSourceisn’t some kind of factory. It’s just the owner of a single token. IMO it should have been calledCancellationTokenOwner.That has nothing to do with debugging. You can’t access a gui control from another thread. You need to use
Invokefor 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.