【问题标题】:How To refresh a windows during a long loop如何在长循环期间刷新窗口
【发布时间】:2015-08-12 20:29:24
【问题描述】:

我正在对文件夹的内容进行长时间循环检查,分为三部分。
p1 -​​ 此文件夹中有超过 5000 个文件夹,
p2 - 每个有约 10 个文件夹,
p3 - 然后每个文件/文件夹的数量未知。

我已经制作了一个最大值 = p1.nbFolder 的进度条 在每个 p1.folder 的末尾,我将 progressbar.Value 加一。 但是窗口冻结并且在每个文件夹末尾刷新窗口的唯一工作是 MessageBox.Show(" ");

this.UpdateLayout();不工作
线程.睡眠(0);都没有

for (int inc = 0; inc < postes.Items.Count; inc++) {
                poste = (TreeViewItem)postes.Items[inc];
                poste.IsSelected = true;
                tranches = (TreeViewItem)tr_tranche.Items[0];
                for (int incb = 0; incb < tranches.Items.Count; incb++) {
                    tranche = (TreeViewItem)tranches.Items[incb];
                    tranche.IsSelected = true;

                    StackPanel SPposte = (StackPanel)poste.Header;
                    Label Lposte = (Label)SPposte.Children[1];
                    String Sposte = (String)Lposte.Content;

                    StackPanel SPtranche = (StackPanel)tranche.Header;
                    Label Ltranche = (Label)SPtranche.Children[1];
                    String Stranche = (String)Ltranche.Content;

                    //str.Append("Poste : " + Sposte + " | Tranche : " + Stranche + " | indice : " + incb + " \n");

                    if (tranche != null) {
                        StackPanel stack = (StackPanel)tranche.Header;
                        Label lbl = (Label)stack.Children[1];
                        String nom = lbl.Content.ToString();

                        tr_folio.Items.Clear();
                        _folio = getDossier(nom, _tranche);
                        //ne filtre rien
                        _folio.getDossiers("a*");
                        _folio.getFichiers();
                        tr_folio.Items.Add(Utils.TreeUtils.ContenuDossier(_folio));
                        lbl_source.Content = _folio.Chemin;

                        TreeViewItem entete = (TreeViewItem)tr_folio.Items[0];
                        entete.IsExpanded = true;
                    }
                    //MessageBox.Show(incb.ToString());
                    tranche.IsSelected = false;
                }
                poste.IsSelected = false;
                pgrB.Value++;
                Thread.Sleep(1);
                this.UpdateLayout();

【问题讨论】:

  • 您应该在后台线程或异步方法中运行您的代码。您正在锁定主线程,这不是一个好的解决方案。
  • 拆分作业并使用DispacherTimer 完成一项作业或将作业放入Task(在调用UI 调用时)。
  • 删除所有这些代码并使用正确的 XAML 和数据绑定。

标签: c# wpf


【解决方案1】:

解决潜在阻塞代码的最佳解决方案之一是使用线程,这样它就不会阻塞 UI 或任何其他代码。它在自己的小世界中运行。

Task mytask = Task.Factory.StartNew(myfunc,aparam);

你甚至可以做(沿着,不放入编码窗口检查语法)

var mytask = Task.Factory.StartNew(myfunc).ContinueWith( result => its_done_func());

所以你可以知道它什么时候完成,你也可以使用一个函数来更新所有的结果。当然你也可以使用 lambda 的

【讨论】:

    【解决方案2】:

    主 UI 线程需要空闲来处理 Windows 消息。如果您将工作移至后台线程,则 UI 线程将能够绘制窗口、响应用户输入(如取消按钮)等。

    有许多使用 WPF 的多线程示例。例如,请参阅 this question 了解一些有用的信息。

    【讨论】:

    • stackoverflow 上的年龄歧视!只是在开玩笑。将链接更改为更相关的 SO 问题。
    【解决方案3】:

    我找到了这个教程。 ProgressBar control tutorial

    Paul > 您的解决方案几乎相同,但我没有找到足够的解释来制定可行的解决方案

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-05-19
      • 2014-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-22
      • 1970-01-01
      相关资源
      最近更新 更多