Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.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.NET';独特的';要得到最新的值?_C#_System.reactive_Reactive Programming_Reactiveui - Fatal编程技术网

C# Rx.NET';独特的';要得到最新的值?

C# Rx.NET';独特的';要得到最新的值?,c#,system.reactive,reactive-programming,reactiveui,C#,System.reactive,Reactive Programming,Reactiveui,我是Rx的新手,我正在尝试制作一个GUI来显示股票市场数据。这个概念有点像,但我需要显示整个“深度”,即市场中的所有价格及其买入/卖出数量,而不仅仅是按价格排序的市场买入/卖出的“顶层” 每个“价格水平”的数据结构如下: public class MarketDepthLevel { public int MarketBidQuantity { get; set; } public decimal Price { get; set; } public int Market

我是Rx的新手,我正在尝试制作一个GUI来显示股票市场数据。这个概念有点像,但我需要显示整个“深度”,即市场中的所有价格及其买入/卖出数量,而不仅仅是按价格排序的市场买入/卖出的“顶层”

每个“价格水平”的数据结构如下:

public class MarketDepthLevel
{
    public int MarketBidQuantity { get; set; }
    public decimal Price { get; set; }
    public int MarketAskQuantity { get; set; }
}
    public IReactiveDerivedList<MarketDepthLevel> MarketDepthStream
    {
        get
        {
            return MarketDepthLevelStream
                .Distinct(x => x.Price)
                .CreateCollection()
                .CreateDerivedCollection(x => x, orderer: (x, y) => y.Price.CompareTo(x.Price));
        }
    }
在GUI下面,一个套接字监听网络更新,并将其作为可观察的数据返回:

IObservable<MarketDepthLevel> MarketPriceLevelStream;
IObservable MarketPriceLevelStream;
转换成反应列表后,最终绑定到DataGrid

转换基本上会选择每个价格级别的最新更新,并按价格进行排序。所以我想出了这样的办法:

public class MarketDepthLevel
{
    public int MarketBidQuantity { get; set; }
    public decimal Price { get; set; }
    public int MarketAskQuantity { get; set; }
}
    public IReactiveDerivedList<MarketDepthLevel> MarketDepthStream
    {
        get
        {
            return MarketDepthLevelStream
                .Distinct(x => x.Price)
                .CreateCollection()
                .CreateDerivedCollection(x => x, orderer: (x, y) => y.Price.CompareTo(x.Price));
        }
    }
public IReactiveDerivedList MarketDepthStream
{
收到
{
返回市场深度流
.Distinct(x=>x.Price)
.CreateCollection()文件
.CreateDerivedCollection(x=>x,order:(x,y)=>y.Price.CompareTo(x.Price));
}
}
但也存在一些问题:

  • 当“Distinct”看到与以前相同的价格时,它会丢弃新的价格,但我需要新的价格来替换旧的价格(因为它们包含最新的MarketBidQuantity/MarketAskQuantity)

  • CreateCollection/CreateDeriveCollection似乎有点笨拙

  • 有没有解决这些问题的想法(特别是第一个问题)?
    谢谢

    只需将项目分组,然后将每组项目投影为组中的最后一项:

    return MarketDepthLevelStream
        .GroupBy(x => x.Price, (key, items) => items.Last());
    

    如果我理解正确,您希望在每个级别的最新出价/要价数量列表中投射一系列
    MarketDepthLevel
    更新(用金融术语来说,这是一种阶梯)。梯形图作为
    反应列表保存在UI中。(可能是必需的,但我相信在大多数情况下,
    ReactiveList
    会处理此问题)

    下面是从中截取的一个示例阶梯,其中“价格”表示为百分比(利率),而买卖规模则表示为各价格水平下贷款人想要的金额和借款人需要的金额:

    在这一点上,我开始有点迷路了。我不明白为什么需要更多的Rx操作符,因为您可以简单地订阅更新流,让处理程序更新绑定到UI的固定列表数据。如果是新的价格,不是每个新事件都需要添加到
    反应列表中,或者用匹配的价格替换现有条目吗?如果这是UI链中的最后一步,那么执行此操作的命令式代码就可以了

    如果您需要将
    MarketDepthLevelStream
    转换为阶梯流,那么在Rx流本身中这样做才有价值。这可能很有用,但你没有提到这个需要

    这种需求可能是由于希望将流多播到多个订户,和/或因为您需要在阶梯上进行进一步的转换或投影

    请记住,如果梯形图很大,那么在UI中使用整个梯形图更新可能会带来性能问题-在许多情况下,将单个更新转换为可变结构(如
    反应列表
    )是一种切实可行的方法

    如果需要使用阶梯流,请查看
    Observable.Scan
    。这是Rx中维护本地状态的工作马操作员。它用于任何形式的运行聚合,如运行总计、平均值等,或者在本例中为阶梯

    现在,如果您只需要上面描述的静态列表,我可能会在这里绕道而行,但这是一个有用的讨论,所以

    您需要仔细考虑梯形图聚合使用的类型—您需要清楚如何使用下游事件。它可能需要一个不可变的集合类型,以便订阅者不会感到奇怪(每个事件实际上都应该是梯形图的静态快照)。使用时,考虑内存效率可能很重要

    下面是一个简单的示例,使用nuget pre-release软件包中的不可变集合,说明梯形图流可能如何工作:

    公共静态类ObservableExtensions
    {
    公共静态IObservable
    ToLadder(此IObservable源)
    {
    返回source.Scan(ImmutableSortedDictionary.Empty,
    (lastLadder,depthLevel)=>
    lastLadder.SetItem(depthLevel.Price,depthLevel));
    }
    }
    
    ToLadder
    扩展方法创建一个空的不可变梯形图作为种子聚合,每个连续的
    MarketDepthLevel
    事件都会生成一个新的更新梯形图。您可能需要查看
    ImmutableSortedSet
    是否足够

    您可能希望将其包装/投影到您自己的类型中,但希望您能得到这个想法


    最终,这仍然给你留下了更新UI的挑战——正如前面提到的,现在你被整个梯形图困住了,这意味着你每次都必须绑定整个梯形图,或者将其转换回一个单独的更新流——而在这里解决这一问题正逐渐脱离主题

    我可能误读了这个问题,但我认为这是行不通的
    Last()
    在源流完成之前不会产生值,我假设因为Rx正在发挥作用,所以需要从一个不断更新的流中显示。@JamesWorld这个问题似乎没有以某种方式描述所需的行为,关于这一点。