[英]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.