繁体   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