2013-05-01 37 views
0

我想做一個小項目來做一些計算並在列表框中添加計算結果。Rx訂閱問題,如何在Winform中更新UI控件中的數據

我的代碼:

 int SumLoop(int lowLimit, int highLimit) 
     { 
      int idx; 
      int totalSum = 0; 
      for (idx = lowLimit; idx <= highLimit; idx = idx + 1) 
      { 
       totalSum += idx; 
      } 
      return totalSum; 
     } 

    private void button1_Click(object sender, EventArgs e) 
     { 
      var test2 = Observable.Interval(TimeSpan.FromMilliseconds(1000)).Select(x=>(int)x).Take(10); 

      test2.Subscribe(n => 
       { 
        this.BeginInvoke(new Action(() => 
         { 
          listBox1.Items.Add("input:" + n); 
          listBox1.Items.Add("result:" + SumLoop(n,99900000)); 
         })); 
       }); 
     } 

其結果是:

input:0 
result:376307504 
(stop a while) 
input:1 
result:376307504 
(stop a while) 
input:2 
result:376307503 
(stop a while) 
input:3 
result:376307501 
(stop a while) 
.... 
... 
.. 
. 
input:"9 
result:376307468 

如果我想從1000修改的時間間隔恆定 - > 10,

var test2 = Observable.Interval(TimeSpan.FromMilliseconds(10)).Select(x=>(int)x).Take(10); 
  1. 顯示行爲變得不同。列表框將顯示所有輸入和結果。它似乎等待所有結果完成,然後顯示一切到列表框。爲什麼?

  2. 如果我想繼續使用這個常量(間隔:10),並不想顯示一切只是一個鏡頭。我想顯示「輸入:0」 - >等待計算 - >顯示「結果:376307504」.... 那麼,我該如何做到這一點?

Thankx對您有所幫助。

回答

0

而不是做control.Invoke/control.BeginInvoke的,你要調用.ObserveOnDispatcher()讓您的操作調用UI線程:

Observable 
    .Interval(TimeSpan.FromMilliseconds(1000)) 
    .Select(x=>(int)x) 
    .Take(10) 
    .Subscribe(x => { 
     listBox1.Items.Add("input:" + x); 
     listBox1.Items.Add("result:" + SumLoop(x, 99900000));     
    }); 

你說,如果你改變的時間間隔從1000毫秒到10毫秒,您會觀察到不同的行爲。

該列表框將顯示所有輸入和結果只是一個鏡頭。

我懷疑這是因爲10ms太快了,你正在執行的所有操作都在排隊。 UI線程來執行它們,並且wham執行所有排隊的事情。

相反,他們發佈的每1000毫秒(一秒)允許UI線程來執行一個,休息,執行另外一個,休息等

3

如果我理解你正確地你想運行總和環關閉UI線程,這裏是你會怎麼做:

Observable 
    .Interval(TimeSpan.FromMilliseconds(1000)) 
    .Select(x => (int)x) 
    .Select(x => SumLoop(x, 99900000)) 
    .Take(10) 
    .ObserveOn(listBox1) // or ObserveOnDispatcher() if you're using WPF 
    .Subscribe(r => { 
     listBox1.Items.Add("result:" + r);     
    }); 

你應該看到的結果滴入在10個毫秒+〜500毫秒的間隔。