[英]Task Does not Update UI in WPF
我写了这段代码:
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);
}
}
它在WPF中有效,但是当我以这种方式编写此代码时;
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);
它不起作用,而txtReport.Text
具有正确的值,但是在操作中间不显示,但是当操作结束时txtReport
显示它的值
为什么这段代码不起作用?
我从未使用过TaskScheduler,因此我不能给你一个错误的直接反馈。 但是从您的问题描述中,我很害羞,问题是UI线程被阻止了。 只要您的代码没有终止,UI就不会更新。
对于耗时的操作,请使用BackgroundWorker进行操作 。 但请注意,不能直接在异步中设置控件的值。 使用分派器将命令路由到UI线程,或使用ProgressChanged -event。
以下代码显示了如何使用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();
ContinueWith
创建一个在目标任务完成时异步执行的延续。 即只有在SumRootN
操作完成后才会更新结果。
有一些故障排除提示...您可能必须先回答这些问题...
TaskScheduler.FromCurrentSynchronizationContext();
您看到什么样的SynchronizationContext
对象? Dispatcher
类型? 还是其他一些类型? BackgroundWorker
和Dispatcher
对?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.