Reputation: 13437
I wrote this code:
public double SumRootN(int root)
{
double result = 0;
for (int i = 1; i < 10000000; i++)
{
tokenSource.Token.ThrowIfCancellationRequested();
result += Math.Exp(Math.Log(i) / root);
}
return result;
}
private void btnclick_Click(object sender, RoutedEventArgs e)
{
tokenSource = new CancellationTokenSource();
txttest.Text = "";
var watch = Stopwatch.StartNew();
List<Task> tasks = new List<Task>();
var ui = TaskScheduler.FromCurrentSynchronizationContext();
for (int i = 2; i < 20; i++)
{
int j = i;
var compute = Task.Factory.StartNew(() =>
{
return SumRootN(j);
}, tokenSource.Token);
tasks.Add(compute);
var displayResults = compute.ContinueWith(
resultTask =>
txttest.Text
+= "root " + j.ToString() + " " +
compute.Result.ToString() +
Environment.NewLine,
CancellationToken.None,
TaskContinuationOptions.OnlyOnRanToCompletion,
ui);
}
}
It works in WPF but when I wrote this code this way;
tokenSource = new CancellationTokenSource();
var watch = Stopwatch.StartNew();
List<Task> tasks = new List<Task>();
var ui = TaskScheduler.FromCurrentSynchronizationContext();
Report
+= ((Microsoft.Office.Interop.Excel.Range)_sheet.Cells[row, "B"]).Value2;
var compute = Task.Factory.StartNew(() =>
{
return Report;
}, tokenSource.Token);
tasks.Add(compute);
var displayResults
= compute.ContinueWith(resultTask =>
txtReport.Text
+= compute.Result.ToString() +
Environment.NewLine,
CancellationToken.None,
TaskContinuationOptions.OnlyOnRanToCompletion,
ui);
It does not work, whereas txtReport.Text
has correct values, but it does not show in the middle of operation but when operation ends txtReport
show it's values
Why does this code not work?
Upvotes: 1
Views: 1510
Reputation: 19885
There are a few troubleshooting tips for this... You may have to answer these questions first...
TaskScheduler.FromCurrentSynchronizationContext();
what kind of SynchronizationContext
object do you see? Dispatcher
type? Or some other type?BackgroundWorker
and Dispatcher
pair?Upvotes: 1
Reputation: 812
ContinueWith
creates a continuation that executes asynchronously when the target Task completes. I.e it will only update the result once your SumRootN
operation complete.
Upvotes: 1
Reputation: 36765
I never worked with TaskScheduler, therefore I can not give you a direct feedback whats wrong. But from your problem description, I'm quite shure that the problem is that the UI-thread is blocked. As long as your code has not terminated, the UI will not be updated.
For time time consuming operations, do them with a BackgroundWorker. However take care that you can not set values of your controls from within the asynchronous directly. Either use the Dispatcher to route your command to the UI-thread or use the ProgressChanged-event.
The following code shows you how to use the BackgroundWorker:
BackgroundWorker bgWorker = new BackgroundWorker() { WorkerReportsProgress=true};
bgWorker.DoWork += (s, e) => {
// Do here your calculations
// Use bgWorker.ReportProgress(); to report the current progress
};
bgWorker.ProgressChanged+=(s,e)=>{
// Here you will be informed about progress and here it is save to set the labels value.
};
bgWorker.RunWorkerCompleted += (s, e) => {
// Here you will be informed if the job is done.
};
bgWorker.RunWorkerAsync();
Upvotes: 1