Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在Rx中存储检索IObservable订阅状态_C#_.net_Serialization_Persistence_System.reactive - Fatal编程技术网

C# 在Rx中存储检索IObservable订阅状态

C# 在Rx中存储检索IObservable订阅状态,c#,.net,serialization,persistence,system.reactive,C#,.net,Serialization,Persistence,System.reactive,[这个问题属于以下领域] 需要在应用程序重新启动时继续的订阅 现在,我需要序列化和反序列化此订阅的状态,以便下次启动应用程序时,缓冲区计数不会从零开始,而是从应用程序退出前缓冲区计数达到的任何值开始 在这种情况下,如何保持IObservable.Subscribe()的状态并在以后加载它 在Rx中保存观察者状态是否有一个通用的解决方案 从答案到解决方案 基于Paul Betts的方法,这里是一个在我的初始测试中工作的半通用实现 使用 扩展方法 private static bool\u-

[这个问题属于以下领域]

需要在应用程序重新启动时继续的订阅 现在,我需要序列化和反序列化此订阅的状态,以便下次启动应用程序时,缓冲区计数不会从零开始,而是从应用程序退出前缓冲区计数达到的任何值开始

  • 在这种情况下,如何保持IObservable.Subscribe()的状态并在以后加载它
  • 在Rx中保存观察者状态是否有一个通用的解决方案


从答案到解决方案 基于Paul Betts的方法,这里是一个在我的初始测试中工作的半通用实现

使用 扩展方法
private static bool\u-readyrecording;
公共静态IObservable记录(此IObservable输入,
IRepositor(再寄存器)
{
IObservable输出=输入;
列表记录=空;
if(repositor.反序列化(ref记录))
{
ISubject history=新的ReplaySubject();
ForEach(history.OnNext);
输出=输入。合并(历史);
}
如果(!\u已记录)
{
_alreadyRecording=true;
Subscribe(i=>repositor.SerializeAppend(新列表{i}));
}
返回输出;
}
公共静态IObservable ClearRecords(此IObservable输入,
IRepositor(再寄存器)
{
Subscribe(i=>repositor.Clear());
返回输入;
}
注释

  • 这不适用于存储依赖于生成的值之间的时间间隔的状态
  • 您需要一个支持序列化T的序列化程序实现
  • \u如果您多次订阅
    myRecordableStream
    ,则需要进行记录
  • \u alreadyRecording
    是一个静态布尔值,非常难看,如果需要并行订阅,则无法在多个位置使用扩展方法-需要重新实现以备将来使用

对于这一点没有通用的解决方案,制作一个将是不平凡的™. 你能做的最接近的事情就是让myStream成为某种可以观察到的重播(也就是说,不要序列化状态,而是序列化myStream的状态,然后重做工作,让你回到原来的状态)

int nValuesBeforeOutput = 123;

myStream.Buffer(nValuesBeforeOutput).Subscribe(
    i => Debug.WriteLine("Something Critical on Every 123rd Value"));
int nValuesBeforeOutput = 123;

var myRecordableStream = myStream.Record(serializer);
myRecordableStream.Buffer(nValuesBeforeOutput).ClearRecords(serializer).Subscribe(
    i => Debug.WriteLine("Something Critical on Every 123rd Value"));
    private static bool _alreadyRecording;

    public static IObservable<T> Record<T>(this IObservable<T> input,
                                           IRepositor repositor) 
    {
        IObservable<T> output = input;
        List<T> records = null;
        if (repositor.Deserialize(ref records))
        {
            ISubject<T> history = new ReplaySubject<T>();
            records.ForEach(history.OnNext);
            output = input.Merge(history);
        }
        if (!_alreadyRecording)
        {
            _alreadyRecording = true;
            input.Subscribe(i => repositor.SerializeAppend(new List<T> {i}));
        }
        return output;
    }

    public static IObservable<T> ClearRecords<T>(this IObservable<T> input,
                                                 IRepositor repositor)
    {
        input.Subscribe(i => repositor.Clear());
        return input;
    }