我有一个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
答案 0 :(得分:1)
在主UI线程上调用有时,应用程序会抛出一个Thread.Abort异常,该异常会被应用程序的未处理异常处理程序捕获。
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);