2014-09-29 24 views
0

我應該首先提到我是編程新手。我會盡我所能解釋我的問題和我的問題。ObjectListView已用時間列可能需要多線程

我想知道是否有可能更新ObjectListView(從這裏稱爲OLV)的單個列。我想要的是有一列將顯示每行的「經過時間」。此已用時間列將每15至30秒刷新一次。

如何設置我OLV

myOLV.SetObjects(GetMyList()); 

GetMyList方法返回從一個簡單的數據庫查詢填充一個列表。

在GetMyList方法中,它會將DateTime列轉換爲顯示已用時間的字符串。這隨後被OLV顯示爲一個字符串,而不是日期時間...

elapsed_time = ((TimeSpan)(DateTime.Now - x.time_arrived)).ToString("hh\\:mm\\:ss"); 

我如何努力使這項工作是通過使用定時器,將每30秒記得GetMyList方法。因爲該方法會重新查詢數據庫並返回它檢索到的記錄,所以它們更新。這工作得很好,直到我有超過20行的OLV。 200行的每個「刷新」需要4秒鐘才能完成。這是用戶界面無響應的4秒鐘...

由於我是新手,我從來沒有對多線程做過任何事情,但是我對它做了一些閱讀並試圖創建一個解決方案。即使當我創建一個新線程來「刷新」OLV對象時,它仍會導致整個表單無響應。

我的問題是,我怎麼能在我的ObjectListView刷新每15-30秒,而不會導致整個用戶界面變得沒有響應? 是否有可能/在後臺刷新ObjectListView然後在準備好時顯示它是一個好主意?

回答

2

問題是數據庫查詢的運行時間,而不是ObjectListView的更新(在ObjectListView中更新200行需要大約200ms)。您需要從UI線程和後臺線程中獲取數據庫。該後臺線程可以定期從數據庫中獲取更新的數據。一旦你有更新的數據,更新ObjectListView是非常快的。

但是,多線程是一個可能咬你的深層次的話題。有很多事情可能會出錯。你最好在UI上有一個按鈕,用戶可以單擊刷新網格,並同步運行所有內容。一旦同步版本完美運行,那麼就開始處理更容易出錯的多線程版本。

要嚴格回答你的問題,你會做這樣的事情:

var thread = new Thread(_ => { 
    while (!_cancelled) { 
     Thread.Sleep(15 * 1000); 
     if (!_cancelled) { 
      var results = QueryDatabase(); 
      this.objectListView1.SetObjects(results); 
     } 
    } 
}); 
thread.Start(); 

_cancelled在類布爾變量,它允許您取消查詢過程。 QueryDatabase()是您獲取新數據的方法。

本示例不處理錯誤,這是後臺線程中的一個重要問題。

另一個問題是,大多數UI組件不能從後臺線程更新,但是,ObjectListView有幾個線程安全的方法,並且SetObjects()就是其中之一,因此您可以像這樣調用它。

只需重複一遍:您應該從同步版開始,只有在您對此感到滿意後纔開始思考異步。