2011-05-09 41 views
2

我有一些代碼,其執行窗口SVC(另一種方法),並更新在同一時間的UI。該呼叫使用BeginInvoke,就像這樣:的BackgroundWorker/Control.BeginInvoke()冷凍UI

Install.BeginInvoke((MethodInvoker) delegate { Install.Enabled = false; }); 

這是DoWork事件處理程序。但是,用戶界面仍然凍結。我需要撥打Application.DoEvents某處(如果有,請在哪裏?)?我怎樣才能消除凍結?

在按鈕的點擊,我有:

GetPrinterDto(DirectoriesTreeView.SelectedNode.Text); 

InstallBackgoundWorker.RunWorkerAsync(); 

InstallBackgroundWorker只是運行它更新UI代碼等

我所試圖做的是調用WCF服務器(在Windows託管服務 - 這很好),但是當它沒有做它的事情時,用異步方式更新進度條和任意值的標籤。當我選擇一個treenode時,會發生選定treenode的事件處理程序,這可能會導致一些減速。我會嘗試把它放在自己的背景工作者中。

+1

你可以發佈一些更多的代碼?有些東西阻礙了你的用戶界面,並且從上面來看,這是無法診斷的。 – 2011-05-09 16:36:43

+0

UI線程當時在做什麼?什麼是「安裝」?它*看起來像*它應該沒問題... – 2011-05-09 16:38:35

+0

安裝是一個按鈕。 – blade33 2011-05-09 16:49:56

回答

4

雖然你肯定可以發出呼叫的DoWork方法來更新UI(這是你對BeginInvoke呼叫正在做),你不應該,否則,你真的不會需要BackgroundWorker類。

相反,你會召喚ReportProgress method然後將火ProgressChanged event

它在ProgressChanged事件的事件處理程序中,您將致電Install.Enabled = false

+0

因此,如果我可以更新所有UI控件?這是實際的修復嗎? – blade33 2011-05-09 16:50:07

+0

@ blade33:是的,ProgressChanged事件的目的是在['SynchronizationContext']中進行調用(http://msdn.microsoft.com/zh-cn/library/system.threading.synchronizationcontext.aspx ),這是呼叫成功所需的;在這種情況下,UI線程。 – casperOne 2011-05-09 17:09:11

+0

另外,我需要在progresschanged事件中調用/ BeginInvoke嗎?無論哪種方式,我仍然滯後。 – blade33 2011-05-09 17:09:54

1

的問題不直接關係到使用的BeginInvoke。它可能與它被調用的次數有關。你可以與ProgressChanged事件一起使用ReportProgress,但假設您更換所有BeginInvoke電話與ReportProgress,那麼你可能會風與類似的問題,因爲BackgroundWorker會自動使用相同的機制元帥在UI線程上執行的事件處理BeginInvoke/Invoke無論如何正在使用。我會說快速解決方案是減少您嘗試更新UI的頻率。

就我個人而言,我認爲使用BeginInvoke更新UI的工作線程進度是方式過度使用。在同樣的方面BackgroundWorker類也促進這種次優的方法。定期向共享數據結構發佈更新信息通常會更好,然後UI線程可以按自己的計劃(通常通過使用Timer進行輪詢)來提取它。這有幾個優點:

  • 它打破了Control.Invoke\Control.BeginInvoke強加的UI和工作線程之間的緊密耦合。
  • 它把更新UI線程,它應該屬於無論如何在UI線程的責任。
  • UI線程到達規定的時間和頻率的更新應該發生。
  • 有被吞沒的無UI消息泵的風險是由工作線程發起的編組技術的情況下。
  • 工作線程在進行下一步之前(即在UI線程和工作線程上獲得更多的吞吐量),不必等待已執行更新的確認。

不幸的是,BackgroundWorker缺乏使用這種替代方法的必要機制。不過,只要你不要太頻繁地調用它,你應該應該可以使用ReportProgress

+0

問題仍然存在(我減少了UI更新)。 Windows svc中的代碼是WMI,這是問題的一部分嗎? – blade33 2011-05-10 08:43:46