看看我的综合性这一非常敏感的话题的研究。如果您无法改善实际性能,您可以采取以下措施:
选项#1执行代码以同一方法同步显示等待消息,它与真正的任务相同。只要把此行一个漫长的过程之前:
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Normal, (Action)(() => { /* Your code to display a waiting message */ }));
它会在的调用()末进程的主线程调度未决的消息。
注意:选择Application.Current.Dispatcher而不是分派器的原因。CurrentDispatcher解释为here。
选项#2显示“等待”屏幕并更新UI(进程挂起消息)。
要做到这一点WinForms开发人员执行Application.DoEvents方法。 WPF提供了两个备选方案,以实现类似的结果:
选项#2.1对于使用DispatcherFrame class。
检查从MSDN有点笨重例如:
[SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public void DoEvents()
{
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background, new DispatcherOperationCallback(ExitFrame), frame);
Dispatcher.PushFrame(frame);
}
public object ExitFrame(object f)
{
((DispatcherFrame)f).Continue = false;
return null;
}
选项#2.2调用一个空的动作
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, (Action)(() => { }));
见讨论哪一个(2.1或2.2)是更好here。恕我直言选项#1仍然比#2好。
选项#3在单独的窗口中显示等待消息。
当您显示的不是一个简单的等待消息,而是一个动画时,它会派上用场。在我们等待另一个长时间渲染操作完成的同时渲染加载动画是一个问题。基本上,我们需要两个渲染线程。在单个窗口中不能有多个渲染线程,但可以将加载动画放入具有自己渲染线程的新窗口中,并使其看起来不是单独的窗口。
下载WpfLoadingOverlay.zip从this github(这是从第一个样本“WPF响应速度:异步加载动画在渲染过程中”,但我找不到它的网站上了),或者看看主要想法如下:
public partial class LoadingOverlayWindow : Window
{
/// <summary>
/// Launches a loading window in its own UI thread and positions it over <c>overlayedElement</c>.
/// </summary>
/// <param name="overlayedElement"> An element for overlaying by the waiting form/message </param>
/// <returns> A reference to the created window </returns>
public static LoadingOverlayWindow CreateAsync(FrameworkElement overlayedElement)
{
// Get the coordinates where the loading overlay should be shown
var locationFromScreen = overlayedElement.PointToScreen(new Point(0, 0));
// Launch window in its own thread with a specific size and position
var windowThread = new Thread(() =>
{
var window = new LoadingOverlayWindow
{
Left = locationFromScreen.X,
Top = locationFromScreen.Y,
Width = overlayedElement.ActualWidth,
Height = overlayedElement.ActualHeight
};
window.Show();
window.Closed += window.OnWindowClosed;
Dispatcher.Run();
});
windowThread.SetApartmentState(ApartmentState.STA);
windowThread.Start();
// Wait until the new thread has created the window
while (windowLauncher.Window == null) {}
// The window has been created, so return a reference to it
return windowLauncher.Window;
}
public LoadingOverlayWindow()
{
InitializeComponent();
}
private void OnWindowClosed(object sender, EventArgs args)
{
Dispatcher.InvokeShutdown();
}
}
我是一样的,当我试图做到单线程。思考,让我们改变光标。但它从未真正奏效。 – Ray 2009-03-05 21:19:17