在WPF中,Windows Forms中的Suspend / ResumeLayout()和BackgroundWorker()相当于什么

如果我在后面的代码中的函数中,并且我想在状态栏中实现显示“正在加载…”,则以下内容是有意义的,但是正如我们从WinForms中知道的那样是NoNo:

StatusBarMessageText.Text = "Loading Configuration Settings..."; LoadSettingsGridData(); StatusBarMessageText.Text = "Done"; 

我们现在从WinForms第1章101类开始,在整个函数完成之前,表单不会显示对用户的更改…这意味着“加载”消息将永远不会显示给用户。 需要以下代码。

 Form1.SuspendLayout(); StatusBarMessageText.Text = "Loading Configuration Settings..."; Form1.ResumeLayout(); LoadSettingsGridData(); Form1.SuspendLayout(); StatusBarMessageText.Text = "Done"; Form1.ResumeLayout(); 

在WPF中处理这个基本问题的最佳做法是什么?

最简单的:

 using(var d = Dispatcher.DisableProcessing()) { /* your work... Use dispacher.begininvoke... */ } 

要么

 IDisposable d; Try { d = Dispatcher.DisableProcessing(); /* your work... Use dispacher.begininvoke... */ } Finally { d.Dispose(); } 

阅读Shawn Wildermuth撰写的文章WPF主题:使用Dispatcher构建更具响应性的应用程序 。

我遇到了以下内容,其中指出您可以像在WindowsForms中一样使用后台工作程序。 想象一下:

BackgroundWorker现在您已经了解了Dispatcher的工作原理,您可能会惊讶地发现在大多数情况下您将无法使用它。 在Windows Forms 2.0中,Microsoft引入了一个非UI线程处理类,以简化用户界面开发人员的开发模型。 该类称为BackgroundWorker。 图7显示了BackgroundWorker类的典型用法。

图7在WPF中使用BackgroundWorker

 BackgroundWorker _backgroundWorker = new BackgroundWorker(); ... // Set up the Background Worker Events _backgroundWorker.DoWork += _backgroundWorker_DoWork; backgroundWorker.RunWorkerCompleted += _backgroundWorker_RunWorkerCompleted; // Run the Background Worker _backgroundWorker.RunWorkerAsync(5000); ... // Worker Method void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { // Do something } // Completed Method void _backgroundWorker_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { statusText.Text = "Cancelled"; } else if (e.Error != null) { statusText.Text = "Exception Thrown"; } else { statusText.Text = "Completed"; } } 

BackgroundWorker组件适用于WPF,因为它在底层使用AsyncOperationManager类,而AsyncOperationManager类又使用SynchronizationContext类来处理同步。 在Windows窗体中,AsyncOperationManager移除了从SynchronizationContext类派生的WindowsFormsSynchronizationContext类。 同样,在ASP.NET中,它使用名为AspNetSynchronizationContext的SynchronizationContext的不同派生。 这些SynchronizationContext派生类知道如何处理方法调用的跨线程同步。

在WPF中,此模型使用DispatcherSynchronizationContext类进行扩展。 通过使用BackgroundWorker,Dispatcher将自动用于调用跨线程方法调用。 好消息是,由于您可能已经熟悉这种常见模式,因此可以在新的WPF项目中继续使用BackgroundWorker。

使其工作的最简单方法是将LoadSettingsGridData添加到调度程序队列。 如果将操作的DispatcherPriority设置得足够低,则会发生布局操作,您将很高兴。

 StatusBarMessageText.Text = "Loading Configuration Settings..."; this.Dispatcher.BeginInvoke(new Action(LoadSettingsGridData), DispatcherPriority.Render); this.Dispatcher.BeginInvoke(new Action(() => StatusBarMessageText.Text = "Done"), DispatcherPriority.Render);