我想从我的 Xamarin 应用观察互联网连接的状态变化。我使用连接插件,它提供了一个连接更改事件,我将其转换为可观察量。这工作正常。
问题是当手机从3G切换到4G时,我想忽略一个短暂的断开连接。
到目前为止,我尝试使用 Throttle
和 Distinct
直到更改,但没有运气,因为即使状态与断开连接之前相同,我也总是得到一个值。
到目前为止,我尝试了这个:
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();
弄清楚"当我不想开火时东西被解雇"发生了什么。幸运的是,Rx有一些强大的测试支持。下面是一些测试代码(使用 Nuget Install-Package Microsoft.Reactive.Testing
)。 source
表示来自 Android API 的噪音。 target
是你在其上的一组运算符。 结果expectedResults
:
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 的通知。您可以通过对运算符进行一些重新排序来摆脱它。看看我的target2
:
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))
);
。如果你想运行测试,这里是运行器代码。
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);
。您将需要这个类
public static class Extensions
{
public static long MsTicks(this int i)
{
return TimeSpan.FromMilliseconds(i).Ticks;
}
}
如果这不能解决您的问题,请增加source
以描述它何时/如何发生。