如何避免口吃/迟滞ui?

时间:2014-03-17 15:29:35

标签: c# wpf

我有一个简单的应用程序读取数据库,然后通过后续操作将结果写入另一个。

第一行代码使用用户消息和屏幕日志更新ui,然后全部包含在try / catch构造中,其中包含usings和其他try / catch annidated。

message.AppendText("** Message for the user that appear only after the try block's execution **\n");
message.ScrollToEnd();
try
{
    using(SqlConnection...)
    {
        business code
    }
}
catch
{
    bbbb...
}

最终它可以工作,但是只有在完成所有操作后才会更新ui。 我可以理解为什么试验中的内容必须等到最后,但为什么第一行不会影响ui直到连续的块结束?

我怎样才能创建更具响应性的ui? 我首先尝试为任何连接创建一个线程(一个时间为5秒),另一个用于业务代码。 好吧,这太过分了,但正在试验。 我在共享线程之间的连接以及与主窗口的交互方面遇到了很多问题,这个窗口放弃了这个想法,并如上所述重写了所有内容。

2 个答案:

答案 0 :(得分:3)

此处有人建议创建自适应用户界面。这是一种方法。在代码文件的顶部,添加:

using System.Threading;

将需要很长时间的所有内容移动到新方法:

public void LoadStuff()
{
    // Do some stuff that takes a while here
}

用以下代码替换原始内容:

Thread callThread = new Thread(new ThreadStart(LoadStuff));
callThread.Start();

现在,只要您需要从LoadStuff更新UI,就必须使用此代码封装它(环绕它)。这样做的原因只是创建UI的线程可以修改它。因此,我们必须告诉我们的新线程返回旧线程来执行代码。因此,在LoadStuff内部,在计算一堆数据之后,要更新UI,请使用:

this.Dispatcher.Invoke(new Action(() =>
{
    // Code to update UI here
}));

与其他人提出的一样,还有其他方法可以提高UI速度,我并不是第一个建议使用不同线程进行计算的人。但我只想告诉你一种方法。

答案 1 :(得分:1)

除了从UI线程中移除长时间运行的进程之外,还有一些UI技巧可以帮助使用户交互感觉更好。例如,如果一个动作花费的时间超过0.1秒,请尝试淡入消息(例如"正在加载...")让用户知道 正在发生的事情。获得数据后,请将此消息淡出。

您可能还想尝试设置动画更新以避免"口吃"感觉。