加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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--------------------------------------

这似乎没有多大意义.你能描述一下你希望结果代表什么,或者纠正我错在哪里?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读