安全地從後台執行緒每30秒更新一次GUI
本文探討如何在應用程式中安全地使用線程,避免錯誤,實現每30秒從後台線程更新GUI的需求。
使用者最初嘗試使用BackgroundWorker並在while循環中運行它,但由於後台工作執行緒不是STA執行緒而導致異常。
正確的做法是將資料庫呼叫與GUI更新分開。資料庫呼叫應在後台執行緒(使用BackgroundWorker)中執行。呼叫完成後,觸發進度事件通知主執行緒更新GUI。
使用者提供的程式碼展示了這個方法:
<code class="language-C#">public class UpdateController { private UserController _userController; private BackgroundWorker _backgroundWorker; // ... public void Update() { _backgroundWorker.RunWorkerAsync(); } void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // UI 更新 _userController.UpdateUsersOnMap(); Update(); // 此处存在潜在问题,递归调用可能导致堆栈溢出 } public void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { // 大型数据库任务 } }</code>
然而,使用者面臨另一個挑戰:如何每30秒觸發一次更新。在RunWorkerCompleted
事件處理程序中加入10秒的休眠不可行,因為它會凍結GUI。
為了解決這個問題,可以使用一個Timer定期呼叫Update
方法,該方法依序啟動資料庫呼叫和隨後的GUI更新。 更佳方案是避免在RunWorkerCompleted
中遞歸呼叫Update()
,而是使用System.Timers.Timer
或System.Windows.Forms.Timer
來控制更新頻率。 這將確保GUI保持回應,並避免潛在的堆疊溢位錯誤。
建議的改進程式碼結構如下 (使用 System.Timers.Timer
):
<code class="language-C#">public class UpdateController { private UserController _userController; private BackgroundWorker _backgroundWorker; private System.Timers.Timer _timer; public UpdateController() { _backgroundWorker = new BackgroundWorker(); _backgroundWorker.DoWork += backgroundWorker_DoWork; _backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted; _timer = new System.Timers.Timer(30000); // 30秒 _timer.Elapsed += Timer_Elapsed; _timer.AutoReset = true; } public void Start() { _timer.Start(); } private void Timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { _backgroundWorker.RunWorkerAsync(); } void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { // UI 更新,确保在UI线程执行 _userController.BeginInvoke(new Action(() => _userController.UpdateUsersOnMap())); } public void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { // 大型数据库任务 } }</code>
這個改進的程式碼利用Timer來控制更新頻率,避免了遞歸呼叫帶來的風險,並使用BeginInvoke
確保UI更新在UI執行緒上執行,從而確保GUI的響應性。 記得在適當的時候呼叫 _timer.Stop()
來停止定時器。
以上是如何每 30 秒從後台執行緒安全地更新一次 GUI?的詳細內容。更多資訊請關注PHP中文網其他相關文章!