2017-01-18 16 views
1

私のXamarin Appからのインターネット接続の状態変化を観察したいと思います。私はObservableに変換するConnectivityChangedイベントを提供するConnectivity Pluginを使用します。これは正常に動作します。リアクティブエクステンション:ショート状態の変更を無視する方法

問題は、電話が切り替わるときなどです。 3Gから4Gまで、私は無視したい短い切断があります。

これまでのところ、ThrottleDistinctを変更してみましたが、結局のところ、状態が切断前のものと同じであっても常に値を取得するため、運がないとしました。

は、これまでのところ、私はこれを試してみました:

var connectionEvent = Observable.FromEventPattern<ConnectivityChangedEventHandler, ConnectivityChangedEventArgs>( handler => handler.Invoke, h => CrossConnectivity.Current.ConnectivityChanged += h, h => CrossConnectivity.Current.ConnectivityChanged -= h) .Select(x => x.EventArgs.IsConnected) .Throttle(TimeSpan.FromSeconds(5)) .DistinctUntilChanged()
.StartWith(CrossConnectivity.Current.IsConnected) .Publish();

答えて

3

それは、「私はそれをしたくない時にスタッフの発火」で何が起こっているのかを把握するために、むしろ難しいです。幸いにも、Rxには堅牢なテストがサポートされています。いくつかのテストコードがあります(Nuget Install-Package Microsoft.Reactive.Testingを使用)。 sourceは、Android APIからのノイズを表します。 targetは、その上にある演算子のセットです。

TestScheduler ts = new TestScheduler(); 
var crossConnectivity_Current_IsConnected = true; 
var source = ts.CreateHotObservable<bool>(
    new Recorded<Notification<bool>>(200.MsTicks(), Notification.CreateOnNext(false)), 
    new Recorded<Notification<bool>>(300.MsTicks(), Notification.CreateOnNext(true)), 
    new Recorded<Notification<bool>>(5550.MsTicks(), Notification.CreateOnNext(false)), 
    new Recorded<Notification<bool>>(5600.MsTicks(), Notification.CreateOnNext(true)), 
    new Recorded<Notification<bool>>(5800.MsTicks(), Notification.CreateOnNext(false)), 
    new Recorded<Notification<bool>>(7700.MsTicks(), Notification.CreateOnNext(true)), 
    new Recorded<Notification<bool>>(7800.MsTicks(), Notification.CreateOnNext(false)), 
    new Recorded<Notification<bool>>(13000.MsTicks(), Notification.CreateOnNext(true)) 
); 

var target = source 
    .Throttle(TimeSpan.FromSeconds(5), ts) 
    .DistinctUntilChanged() 
    .StartWith(crossConnectivity_Current_IsConnected); 

var expectedResults = ts.CreateHotObservable<bool>(
    new Recorded<Notification<bool>>(0.MsTicks(), Notification.CreateOnNext(true)), 
    new Recorded<Notification<bool>>(5300.MsTicks(), Notification.CreateOnNext(true)), 
    new Recorded<Notification<bool>>(12800.MsTicks(), Notification.CreateOnNext(false)), 
    new Recorded<Notification<bool>>(18000.MsTicks(), Notification.CreateOnNext(true)) 
); 

私が見ている唯一の問題は5300に通知あなたはビット演算子を再注文しているのを取り除くことができますが、次のとおりです。expectedResultsは結果です。

var target2 = source 
    .Throttle(TimeSpan.FromSeconds(5), ts) 
    .StartWith(crossConnectivity_Current_IsConnected) 
    .DistinctUntilChanged() 
    ; 

var expectedResults2 = ts.CreateHotObservable<bool>(
    new Recorded<Notification<bool>>(0.MsTicks(), Notification.CreateOnNext(true)), 
    new Recorded<Notification<bool>>(12800.MsTicks(), Notification.CreateOnNext(false)), 
    new Recorded<Notification<bool>>(18000.MsTicks(), Notification.CreateOnNext(true)) 
); 

...とあなたがテストを実行したい場合は、ここではランナーのコードは次のとおりです。私のtarget2を見てください。

var observer = ts.CreateObserver<bool>(); 
target.Subscribe(observer); 
var observer2 = ts.CreateObserver<bool>(); 
target2.Subscribe(observer2); 
ts.Start(); 

ReactiveAssert.AreElementsEqual(expectedResults.Messages, observer.Messages); 
ReactiveAssert.AreElementsEqual(expectedResults2.Messages, observer2.Messages); 

...そしてそれは、それが発生したときに/どのように記述するためにsourceを強化、あなたの問題が解決しない場合は、このクラス

public static class Extensions 
{ 
    public static long MsTicks(this int i) 
    { 
     return TimeSpan.FromMilliseconds(i).Ticks; 
    } 
} 

が必要になります。

+0

ありがとう、驚くべきことに、私はそれを変更してはいけない、そうですか? – Thomas

+0

並べ替えが重要でした。ありがとうございました – Thomas

+1

ヘルパーメソッドを使用して、 'ReactiveTest.OnNext(200.MsTicks()、false) 'に'新しいRecorded >(200.MsTicks()、Notification.CreateOnNext(false) 、 '。さらに、テストクラスが 'ReactiveTest'を基本クラスとして使用する場合は、' OnNext(200.MsTicks()、false)、 'にさらに減らされます。同じトリックを使用して、そしてあなたが 'AssertEqual'のEXTメソッドを使用することができ、あなたのアサーションは' observer2.Messages.AssertEqual( \t \t OnNext(0.MsTicks()、真)、 \t \tに減らすことができるということに気づいOnNext (12800.MsTicks()、false)、 \t \t OnNext(18000.MsTicks()、true)); ' –

関連する問題