c# – 使用Rx执行延迟采样的最佳方法是什么?
发布时间:2020-12-15 22:46:11 所属栏目:百科 来源:网络整理
导读:我正在开发一个Xamarin应用程序,我已经扩展了 Connectivity插件以使用Rx而不是事件. 我的目标是在重新建立连接时引入一点延迟,以允许网络适配器有时间连接到互联网(UWP的解决方法).如果在此延迟中出现任何值,则只需保留最后一个值,因为只有当前连接状态很重
我正在开发一个Xamarin应用程序,我已经扩展了
Connectivity插件以使用Rx而不是事件.
我的目标是在重新建立连接时引入一点延迟,以允许网络适配器有时间连接到互联网(UWP的解决方法).如果在此延迟中出现任何值,则只需保留最后一个值,因为只有当前连接状态很重要. 这很好,但感觉有点hacky: internal static class ConnectivityExtensions { public static IObservable<bool> ToObservable(this IConnectivity @this) { var connectivity = Observable .FromEventPattern<ConnectivityChangedEventHandler,ConnectivityChangedEventArgs>( handler => @this.ConnectivityChanged += handler,handler => @this.ConnectivityChanged -= handler) .Select(args => args.EventArgs.IsConnected); var sampling = connectivity .Timestamp() .Select(ts => new { ts.Value,ts.Timestamp,// If reconnection,delay subscriber notification for 250ms DelayUntil = ts.Value ? (DateTimeOffset?)ts.Timestamp.Add(TimeSpan.FromMilliseconds(250)) : null }) .Scan((acc,current) => new { current.Value,current.Timestamp,// If current notification is during reconnection notification delay period,delay the current notification too DelayUntil = current.Timestamp < acc.DelayUntil ? acc.DelayUntil : current.DelayUntil }) // Perform reconnection delay .Delay(x => x.DelayUntil.HasValue ? Observable.Return(x.DelayUntil.Value).Delay(x.DelayUntil.Value) : Observable.Empty<DateTimeOffset>()) // All delayed notifications are delayed until the same time,so we only need one notification to trigger sampling after delay .DistinctUntilChanged() .Select(_ => Unit.Default); return connectivity .Sample(sampling) .StartWith(@this.IsConnected) .DistinctUntilChanged() .Replay(1) .RefCount(); } } 示例输出: 通过这个例子,你可以看到我正在做的事情的好处.当“连接”改变时,延迟阻止订户处理数据,但是尚未建立互联网连接(UWP).此外,这还可以保护用户免受任何快速“开/关”通知. // StartsWith: True ConnectivityChanged(null,new ConnectivityChangedEventArgs { IsConnected = true }); // Delay 250ms Thread.Sleep(TimeSpan.FromMilliseconds(250)); // Sample: True,Ignored due to DistinctUntilChanged ConnectivityChanged(null,new ConnectivityChangedEventArgs { IsConnected = false }); // Sample: False Thread.Sleep(TimeSpan.FromMilliseconds(250)); ConnectivityChanged(null,new ConnectivityChangedEventArgs { IsConnected = true }); // Delay 250ms,Discarded due to Sample ConnectivityChanged(null,new ConnectivityChangedEventArgs { IsConnected = false }); // Delayed by previous,new ConnectivityChangedEventArgs { IsConnected = true }); // Delayed by previous,new ConnectivityChangedEventArgs { IsConnected = false }); // Delayed by previous Thread.Sleep(TimeSpan.FromMilliseconds(250)); // Sample: False,Ignored due to DistinctUntilChanged // Final Output: // True // False 有没有更优化的方法来实现这种类型的延迟采样? 解决方法
如果我理解正确,这是一个大理石图,说明事情将如何解决:
T (millis) : 0----250--500--1000-1250-1500-1750-2000 Connectivity : ---F-------T---F----T-------F--T------- ScanValueDelayUntil : ---null----800-null-1500----null2100--- Sampling : -------------x-----------x-----------x- ResultSampled : T------------T-----------T-----------T- ResultSampledDistinct: T-------------------------------------- 这似乎没有多大意义.你能描述一下你希望结果代表什么,或者纠正我错在哪里? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |