WPF启动接口而不冻结GUI

时间:2013-05-22 09:16:27

标签: wpf multithreading loading

我知道有很多关于在不同线程中初始化东西的线程,所以你不需要冻结你的UI。但在我的情况下,这个初始化涉及创建大量的图(画布中的折线),因此它似乎需要冻结UI。

隐藏正在初始化事物的帧可能已经足够了(我已经在下面放了一个“loading ..”消息)然后冻结UI(几秒钟),然后再次显示帧。

这是我到目前为止所拥有的。但是没有工作......它在隐藏任何内容之前冻结UI,并在加载完全初始化帧后解冻。 否则,这件事就像一个魅力。

void Historics_showExperimentResults(object sender, EventArgs e)
    {
        aepPage = new AEPPage();
        resultsPage = new AEPResultSet();

        // I try to hide the frame. Below there is a "Loading..." nice text.
        // not sure if it's the best way but it works if I dont show anything at the end
        ParadigmFrame.Dispatcher.Invoke((Action)delegate
        {
            ParadigmFrame.Content = null;
            ParadigmFrame.UpdateLayout();
        });

        // This is the initialization that needs to have the GUI thread
        //because it draw some plots and polylines
        aepPage.Dispatcher.Invoke((Action)delegate
        {
            aepPage.init(resultSet);
        });

        //Then I want to go and visualize the initialized page with the plots
        ParadigmFrame.Dispatcher.Invoke((Action)delegate
        {
            ParadigmFrame.Navigate(aepPage);
        });
    }

任何线索???正如我所说,我试图将init放在一个不同的线程中,并在完成时添加一个事件,但是这个线程需要控制UI来初始化画布中的折线,所以......它不起作用:(

提前致谢!

2 个答案:

答案 0 :(得分:0)

看起来Historics_showExperimentResults已经在UI线程上运行了。试试这个:

 void Historics_showExperimentResults(object sender, EventArgs e)
        {
            aepPage = new AEPPage();
            resultsPage = new AEPResultSet();

            new Thread(_ =>
            {
              // I try to hide the frame. Below there is a "Loading..." nice text.
              // not sure if it's the best way but it works if I dont show anything at the end
              ParadigmFrame.Dispatcher.Invoke((Action)delegate
              {
                ParadigmFrame.Content = null;
                ParadigmFrame.UpdateLayout();
              });

              // This is the initialization that needs to have the GUI thread
              //because it draw some plots and polylines
              aepPage.Dispatcher.Invoke((Action)delegate
              {
                  aepPage.init(resultSet);
              });

              //Then I want to go and visualize the initialized page with the plots
              ParadigmFrame.Dispatcher.Invoke((Action)delegate
              {
                  ParadigmFrame.Navigate(aepPage);
              });
            }).Start();
        }

答案 1 :(得分:0)

我不会将此标记为答案,因为它不是......但仍然是我现在正在使用的解决方法。

我所做的是将淡出,初始化和淡入淡出分成碎片。

我创建了一个故事板,淡出并将下一步附加到Finished事件,因此,在某种伪代码中它将是:

StoryBoard sb = new StoryBoard;
OnClick(object sender blabla)
{
    storyBoard.add(fade out animation over ParadigmFrame);
    storyBoard.Completed += performInit;
    storyBoard.Begin();
}

所以这个部分被执行了,paradigmFrame消失了,显示下面的“加载...”信息。 然后..

private blabla performInit()
{
    aepPage.Dispatcher.Invoke((Action)delegate
          {
              aepPage.Finished += initFinished; 
              aepPage.init(resultSet);
          });
}

我确实在aepPage类中创建了Finished事件,并在初始化完成后触发了它。因此,在所有这些过程中,UI都是冻结的。 “正在加载...”消息是可见的并且它不是很糟糕但是REAL解决方案不应该冻结这里的UI ... 然后我出现了

private void initFinished()
{
    storyBoard.add(fade in animation over ParadigmFrame);
    storyBoard.Completed -= performInit;
    storyBoard.Begin();
}

这是我漫长而丑陋的解决方法......我仍然对新的解决方案持开放态度!

谢谢!