页面加载时的进度指示器

时间:2012-03-12 12:57:12

标签: c# wpf multithreading

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

我已经使用选项1实现了应用程序,但我遇到了以下问题: 1.有时,应用程序将抛出一个Thread.Abort异常,该异常会被应用程序的未处理异常处理程序捕获。 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

2 个答案:

答案 0 :(得分:1)

  

有时,应用程序会抛出一个Thread.Abort异常,该异常会被应用程序的未处理异常处理程序捕获。

在主UI线程上调用

Thread.Abort。这是例外的来源。它可能正在发生,因为在UI线程中调用Dispose(通过using构造)和自己退出ProgressWaitDialog方法的ShowDialog之间存在竞争大概是在代码的其他地方调用Close之后。

  

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

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

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

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

答案 1 :(得分:0)

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

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