【问题标题】:Invoke and task not working调用和任务不起作用
【发布时间】:2018-05-11 08:01:43
【问题描述】:

我正在用 C# 编写一个程序,我有一个问题,我想在每次循环后从不同类中的方法更新视图上的 Label 和 ProgressBar。但是,它不是在每个循环之后而是在方法结束时更新这些控件。如何解决? Task.Run (() => methodFromAnotherClass ()) 根本不起作用,当我使用 Invoke.Dispatcher 并将控件作为参数传递给方法时,更新仅在方法结束时发生,并且不是在每个循环之后。

private void buttonStart_Click(object sender, RoutedEventArgs e)
{
    FindDocument findDocument = new FindDocument(labelCurrentNumber, progressBar1);
    cProgress<int> progress = new Progress<int>();
    progress.ProgressChanged += (p, value) => { progressBar1.Value = value; labelCurrentNumber.Content = value.ToString(); };
    //Task.Run(() => findDocument.Find(csvRows, mode, (int)slider.Value, 1, check, progress, outputFileCsv));
    findDocument.Find(csvRows, mode, (int)slider.Value, 1, 1, progress, outputFileCsv);
}

以上是视图中的代码。

public int Find(List<CsvModel> csvRows, SearchMode PageMode, int PageMargin, double sensitivity, int pageInfo, IProgress<int> progress, string outPath)
{
    csvContent.AppendLine("sep=,");
    csvContent.AppendLine("Lp,Plik wejściowy, Plik wyjściowy, Wynik");

    foreach (CsvModel csv in csvRows)
    {
        progressReport++;
        progress.Report(progressReport);

        lab.Dispatcher.InvokeAsync(() => lab.Content = progressReport.ToString());
        this.lab.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Send, new Action(() => lab.Content = progressReport));
    }
    File.WriteAllText(outPath + @"\dane.csv", csvContent.ToString());
    logger.Info($"Zakończono przetwarzanie obrazu");
    return 0;
}

上面是另一个类的代码,该方法作为参数控件提供。 我做错了什么?

【问题讨论】:

  • 程序甚至没有调用这个方法。当我使用 Task.Run() 在此方法中设置断点时,程序甚至没有进入此方法。
  • 请记住,UI 元素不是线程安全的。您是否尝试过改用ThreadPool.QueueUserWorkItem();

标签: c# wpf controls


【解决方案1】:

如果您同步运行此程序(就像您目前所做的那样),UI 将被阻止直到方法结束,因此您看不到进度更改。

如果你使用Task,你可能会得到错误,因为我不相信progress.ProgressChanged 是线程安全的。您可以在报告进度时使用 Dispatcher.InvokeContorl.Invoke ( progress.Report(progressReport);) 或在事件本身中使用 (progressBar1.Value = value; labelCurrentNumber.Content = value.ToString();)

【讨论】:

  • 我将其更改为 Dispatcher.Invoke for progressBar 和 Label,但仍然无法正常工作。我不使用progress.Report。仍然 UI 就像被阻止或什么的。我只能在方法停止工作后才能看到更改,但在工作期间视图没有改变。
  • 也许这个方法太快了?尝试在 foreach 循环中添加一些延迟(Thread.Sleep(100)),看看会发生什么。
  • 这不是速度的问题。整个问题是,当我调用 Task.Run 时,根本没有调用该函数,但是当我在没有 Task.Run 的情况下调用函数时,它可以工作,但 UI 被阻止以使方法停止工作
猜你喜欢
  • 2017-10-21
  • 2019-06-01
  • 2015-05-31
  • 1970-01-01
  • 2017-03-29
  • 2013-07-10
  • 2016-04-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多