页面加载时的进度指示器

本文关键字:指示器 加载 | 更新日期: 2023-09-27 18:27:25

我有一个WPF窗口,大约需要5秒才能加载。我想用一条用户友好的消息通知用户,但不确定最好的方法。我能想到的两件事:1.弹出一个显示消息的对话框,一旦加载主窗口,消息就会消失。2.使用主窗口上的面板显示消息,并将UI加载到隐藏面板中。加载后,切换可见性,使加载进度面板隐藏,并使UI面板可见。

我已经使用选项1实现了应用程序,但遇到了以下问题:1.偶尔,应用程序会抛出Thread.Artrt异常,该异常被应用程序的未处理异常处理程序捕获。2.用户可以关闭进度对话框,但主窗口仍在加载。

我对进度对话框的实现相当简单。它只使用一个带有消息的普通对话框,然后我编写了一个助手类来管理它:

public class ProgressWaitDialogHelper : IDisposable
{
    private Thread _thread = null;
    private ProgressWaitDialog _waitDialog;
    public void ShowDialog()
    {
        ThreadStart threadStart = new ThreadStart(ShowDialogAsync);
        _thread = new Thread(threadStart);
        _thread.SetApartmentState(ApartmentState.STA);
        _thread.Start();
    }
    public void Dispose()
    {
        if ((_thread != null) &&
            (_thread.IsAlive))
        {
            _thread.Abort();
            _thread = null;
        }
    }
    private void ShowDialogAsync()
    {
        _waitDialog = new ProgressWaitDialog();
        _waitDialog.ShowDialog();
    }
}

我的呼叫代码是:

using (ProgressWaitDialogHelper waitDialog = new ProgressWaitDialogHelper())
{
    waitDialog.ShowDialog();
    // Do long running UI update loading here.
}

有人知道我该如何解决我看到的问题吗?此外,转到解决方案2是否更好?或者,有没有其他更符合WPF的方法来做到这一点?

TIA

页面加载时的进度指示器

偶尔,应用程序会抛出Thread.Artrt异常,该异常会被应用程序的未处理异常处理程序捕获。

CCD_ 1正在主UI线程上被调用。这就是异常的来源。之所以会发生这种情况,可能是因为在UI线程中调用Dispose(通过using构造)和ProgressWaitDialog(可能是在从代码中的其他地方调用Close之后)自行退出其ShowDialog方法之间存在竞争。

用户可以关闭进度对话框,但主窗口仍在加载。

进度对话框可以在不影响主窗口的情况下关闭,因为它在单独的线程上运行。

我建议不要在另一个线程上运行ProgressWaitDialog,顺便说一句,它只能正常工作一半,因为ShowDialog会泵送消息。使用多个UI线程是很棘手的,会导致很多奇怪的问题,其中一些问题你已经观察到了。

您确实需要重新考虑UI线程上的长操作是如何进行的。如果它涉及到从数据库加载数据、进行集群计算,或者不需要触摸任何UI控件,那么该部分可以在工作线程中执行。如果这个长操作需要进行大量的UI操作,那么您需要将其中的一些操作推迟到以后。例如,如果您的窗口正在用10000条记录填充一个网格,那么请对其进行更改,使其一次只加载100条,并实现某种分页策略,仅在用户单击按钮或其他操作后加载下一批。

这是向用户显示表单正在加载的一种干净而有吸引力的方式。

var splashScreen = 
    new SplashScreen(System.Reflection.Assembly.GetExecutingAssembly(),
    @"Resources'MyAppsLogo.png");
splashScreen.Show(true);