2014-03-01 97 views
0

我最初使用ObservableClass來每秒存儲CPU使用率信息,並將這些信息移動到一個工作正常的圖表中,但它一直在添加到內存中。使用隊列類來管理內存

得到了一些建議,並移動到選擇一個Queue類,以便能夠在一段時間過去後刪除信息。但與可觀察的類不同,我不能存儲2個參數。

我應該使用隊列和可觀察類還是隊列類都足以解決我的問題。使用可觀察類

class CPUClass{ 
    ObservableCollection<KeyValuePair<double, double>> cpuChartList = new ObservableCollection<KeyValuePair<double, double>>(); 

    //this method is fired off every second 
    private void timerChange(){ 
     counter += 1; 
     //cpuCurrent is the current cpu usage value every second 
     cpuChartList.Add(new KeyValuePair<double, double>(counter, cpuCurrent)); 
    } 
} 

//On the MainWindow 
cpulineChart.DataContext = CPUClass.cpuChartList; 

與隊列類試圖

初始代碼

class CPUClass{ 
    Queue queueCPU = new Queue(); 

    //to hold past 30 seconds cpu usage information at any point 
    private void timerChange(){ 
     counter += 1; 
     if (queueCPU.Count > 30) 
      { 
       queueCPU.Dequeue(); 
       counter -= 1; 
      } 
     queueCPU.Enqueue(cpuCurrent);// 
    } 
} 

//On the MainWindow 
cpulineChart.DataContext = CPUClass.queueCPU; 

你可以使用Queue類的時候看到的,我不能夠包括我的櫃檯上保持幾秒鐘的軌道圖表。這對我來說是新的,因此可能會混淆整個概念。還在思考如果我爲Queue Class方式添加和刪除計數器的方式是混亂的。請指教。謝謝。

+0

檢查該SO張貼用於實現固定長度隊列 - http://stackoverflow.com/questions/5852863/fixed-size-queue-which-automatically-dequeues-old-values-upon-new-enques – siddharth

+0

Tnks for reply。我正在尋找一種實現隊列的方式,以便它採用2個類似於ObservableCollection的參數。 – kar

回答

1

我還沒有在這裏使用隊列,但我認爲這是你想要做的。您希望每秒更新一次可觀察集合並移除存儲在其中的最古老的項目。基於此,我提供了下面的代碼。

希望這會有所幫助。

public class CPUClass 
{ 
    public ObservableCollection<KeyValuePair<double, double>> cpuChartList = new ObservableCollection<KeyValuePair<double, double>>(); 
    private object _lock = new object(); 
    private int _counter; 
    private int _Limit = 30; //max 30 secs of data 

    Timer _timer; 

    public CPUClass() 
    { 
     _timer = new Timer(1000); 
     _timer.Elapsed += _timer_Elapsed; 
     _timer.Enabled = true; 

     _counter = 0; 

    } 

    void _timer_Elapsed(object sender, ElapsedEventArgs e) 
    { 
     App.Current.Dispatcher.Invoke(() => UpdateCollection()); 
    } 

    void UpdateCollection() 
    { 
     lock (_lock) 
     { 
      _counter += 1; 

      //Get the CpuUsage 
      var cpuCurrent = GetCpuUsage(); 

      //Remove the oldest item 
      if (cpuChartList.Count >= _Limit) 
       cpuChartList.RemoveAt(0); 
      cpuChartList.Add(new KeyValuePair<double, double>(_counter, cpuCurrent)); 
     } 
    } 


} 
+0

這起作用。只是想澄清一些事情。當您使用.RemoveAt方法時,是否從內存中清除該信息或仍然保存在背景中? – kar

+0

該對象在從集合中移除後會保留在內存中,直到其標記爲由垃圾收集器處理。你可以使用'GC.Collect'強制垃圾收集,但通常不推薦。你可以在這裏閱讀它 - http://stackoverflow.com/questions/1149197/gc-collect。此外,如果你想強制GC.Collect,你可以在每隔60秒左右說出一個條件來做這件事。 'if(_counter%60 == 0){GC.Collect; }' – siddharth

+1

謝謝你解釋。 :) – kar