2010-12-03 20 views
1

ネイティブ.NETイベントから作成されたIObservableからIEnumerableを取得しようとすると、最初の要素を照会するときにIEnumerableがブロックされます。私は間違って何をしていますか?Observable.FromEvent(...)を取得できません。ToEnumerable()が動作する

私は小さな完全な例を作りました。最初のテストメソッドはブロックされますが、イベントは別のIObservableによって正しくプッシュされます。 2番目のテスト方法はプレーンな配列で動作し、ブロックされません。

ありがとうございます!

using System; 
using System.Linq; 
using Microsoft.VisualStudio.TestTools.UnitTesting; 

namespace TestGTI.Reactive 
{ 

    class ItHappenedEventArgs : EventArgs 
    { 
    } 

    class A 
    { 
     public event EventHandler<ItHappenedEventArgs> ItHappened; 

     public void RaiseItHappened(ItHappenedEventArgs e) 
     { 
      if (ItHappened != null) 
      { 
       ItHappened(this, e); 
      } 
     } 
    } 

    [TestClass] 
    public class ReactiveTest 
    { 
     [TestMethod] 
     public void EnumerateEventTest() 
     { 
      var a = new A(); 

      ItHappenedEventArgs pushed = null; 
      Observable.FromEvent<ItHappenedEventArgs>(a, "ItHappened").Subscribe(e => 
       { 
        pushed = e.EventArgs; 
       }); 

      var itHappenedEnum = Observable.FromEvent<ItHappenedEventArgs>(a, "ItHappened").ToEnumerable(); 

      var itHappenedEventArgs = new ItHappenedEventArgs(); 
      a.RaiseItHappened(itHappenedEventArgs); 

      Assert.AreSame(itHappenedEventArgs, pushed); 

      // blocks!!! 
      Assert.AreSame(itHappenedEventArgs, itHappenedEnum.First());   
     } 

     [TestMethod] 
     public void ObservableToEnumerableTest() 
     { 
      var array = new int[] { 1, 2, 3 }; 
      var enumerable = array.ToObservable().ToEnumerable(); 

      // works 
      Assert.AreEqual(1, enumerable.First()); 
     } 
    } 
} 

答えて

3

それが列挙型に来るときIEnumerableは怠け者である、とあなたが列挙を開始するまでToEnumerableがソースに加入していません。

の後にのイベントを初めて呼び出すと、ソースに登録していて値が送出されないため、ブロックされます。基本的には、あなたが聴いている時には、価値はすでに消えてしまっています。

値を覚えたい場合は、PruneまたはReplayを使用できます(リスニングを開始するには、返されたIConnectableObservableに接続することを忘れないでください)。 ToEnumerableを使用すると、値が出力されます。

+0

あなたが正しいです、GetEnumerator()が呼び出されるとサブスクリプションが発生します。 Replay()は私が探していたものです。ありがとう! – Ernesto

+0

あなたは大歓迎です:) –

0

リチャードがここにありますが、これも概念的な視点から追加したいと思います。IEnumerableは通常(実際には必須ではありませんが)有限のサイズのリストの抽象です。 FromEventは決して終了しないIObservableです - 無限大のリストを作成するのは意味がありますか?私ができることはそれほど実用的ではありません。

+0

無限リストを保持する能力は、IEnumerableの主な用途の1つであり、このような方法でイベントを処理することは、概念的にはRxの基礎の1つです。 –

関連する問題