C# Backgroundworker/Control.BeginInvoke()冻结用户界面

C# Backgroundworker/Control.BeginInvoke()冻结用户界面,c#,winforms,backgroundworker,begininvoke,C#,Winforms,Backgroundworker,Begininvoke,我有一些代码,它执行windows svc另一个进程,同时更新UI。这些调用使用BeginInvoke,如下所示: Install.BeginInvoke((MethodInvoker) delegate { Install.Enabled = false; }); 这在DoWork事件处理程序中。但是,UI仍然冻结。我需要打电话到Application.DoEvents某处吗?如果需要,在哪里??我怎样才能消除冰冻 在单击按钮时,我有: GetPrinterDto(DirectoriesTr

我有一些代码,它执行windows svc另一个进程,同时更新UI。这些调用使用BeginInvoke,如下所示:

Install.BeginInvoke((MethodInvoker) delegate { Install.Enabled = false; });
这在DoWork事件处理程序中。但是,UI仍然冻结。我需要打电话到Application.DoEvents某处吗?如果需要,在哪里??我怎样才能消除冰冻

在单击按钮时,我有:

GetPrinterDto(DirectoriesTreeView.SelectedNode.Text);

InstallBackgoundWorker.RunWorkerAsync();
InstallBackgroundWorker只运行更新UI等的代码

我试图做的是调用托管在windows服务中的WCF服务器-这很好,但是在停止工作的同时,以异步方式用任意值更新进度条和标签。当我选择一个treenode时,所选treenode的事件处理程序会失效,这可能会导致一些减速。我将尝试将其放在它自己的backgroundworker中。

虽然您当然可以在DoWork方法中调用BeginInvoke来更新UI,但您不应该这样做,否则,您真的不需要backgroundworker类

相反,您可以调用,然后调用


您将在ProgressChanged事件的事件处理程序中调用Install.Enabled=false。

该问题与BeginInvoke的使用没有直接关系。这可能与它被调用的次数有关。您可以将ReportProgress与ProgressChanged事件结合使用,但是假设您用ReportProgress替换所有BeginInvoke调用,那么您可能会遇到类似的问题,因为BackgroundWorker将使用BeginInvoke/Invoke所使用的机制自动封送UI线程上的事件处理程序。我想说的是,快速解决方案是减少您尝试更新UI的频率

就我个人而言,我认为使用BeginInvoke来更新具有工作线程进度的UI是过度使用的。同样,BackgroundWorker类也推广了这种次优方法。通常最好让工作线程定期将更新信息发布到共享数据结构中,然后UI线程可以按照自己的时间表(通常通过使用计时器轮询)获取更新信息。这有几个优点:

它打破了Control.Invoke\Control.BeginInvoke强加的UI和工作线程之间的紧密耦合。 它将更新UI线程的责任放在它应该属于的UI线程上。 UI线程可以指定更新的时间和频率。 UI消息泵不会像工作线程启动的封送处理技术那样溢出。 工作线程不必等待更新已执行的确认,然后再继续执行下一步,即,您可以在UI和工作线程上获得更高的吞吐量。
不幸的是,BackgroundWorker缺乏使用这种替代方法的必要机制。但是,只要不太频繁地调用ReportProgress,您就可以使用它。

您可以发布更多的代码吗?有东西阻塞了你的UI,从上面看,无法诊断。UI线程当时在做什么?什么是安装?看起来应该没问题…所以万一我可以更新所有的UI控件?这是实际修复吗?@blade33:是的,ProgressChanged事件的目的是在中进行调用,这是调用成功所必需的;在本例中,是UI线程。另外,我是否需要在progresschanged事件中调用/BeginInvoke?无论哪种方式,我仍然会有延迟。我知道,在单击按钮之前选择一个需要的treeview节点时,大约有10-15行设置变量,但没有穿过网络等。可能这也需要自己的后台工作程序?@blade33:不,您不需要在ProgressChanged事件中调用Invoke/BeginInvoke;将在UI线程上调用ProgressChanged事件。如果您遇到延迟,这是因为您更新UI线程的频率太高,或者您在安装实例上将Enabled设置为true的结果调用的操作花费的时间太长。我不能说,我不知道您是否有任何东西绑定到Enabled标志。问题仍然存在,我已经减少了UI更新。windows svc中的代码是WMI,这是问题的一部分吗?