看看我的綜合性這一非常敏感的話題的研究。如果您無法改善實際性能,您可以採取以下措施:
選項#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