簡體   English   中英

任務不會更新WPF中的UI

[英]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操作完成后才會更新結果。

有一些故障排除提示...您可能必須先回答這些問題...

  1. 您的代碼實際位於哪里? 在Button_click()中調用?
  2. 將brekapoint放在代碼上的TaskScheduler.FromCurrentSynchronizationContext(); 您看到什么樣的SynchronizationContext對象? Dispatcher類型? 還是其他一些類型?
  3. 是否有使用TPL的特定原因? 不能使用BackgroundWorkerDispatcher對?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM