2013-05-01 1 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)를 계속 사용하고 싶을뿐 모든 장면을 표시하고 싶지 않습니다. "Input : 0"-> 계산 대기 -> "result : 376307504"...을 표시하고 싶습니다. ... 그럼 어떻게하면됩니까?

감사합니다. 대신 control.Invoke/control.BeginInvoke을하는

답변

0

, 당신은 .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));     
    }); 

당신은 당신이 간격을 변경하는 경우 말했다 1000ms에서 10ms로, 당신은 다른 행동을 관찰합니다.

목록 상자에는 모든 입력과 결과가 표시됩니다.

이것은 10ms가 빠르기 때문에 발생하는 모든 동작이 대기열에 들어가기 때문입니다. UI 스레드는 실행을 위해 돌아오고, 대기하고있는 모든 것을 실행합니다. 그들에게 모든 1000MS (1 초) 게시 대조적으로

는 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);     
    }); 

당신은 결과가 10ms의 + ~ 500ms로의 간격에 조금씩 볼 수 있습니다.

관련 문제