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