public static IDisposable Subscribe <T, TKey>(this IGroupedObservable <T, TKey> value, Action <T> onNext) { Observer <T> observer = new Observer <T>(onNext); IDisposable subject = value.Subscribe(observer); return(subject); }
private static IObservable <TValue> DebounceWithSelector <TKey, TValue>(this IGroupedObservable <TKey, TValue> source, TimeSpan dueTime, Func <TValue> itemSelector, IScheduler scheduler) { return(Observable.Create <TValue>(o => { var disposables = new CompositeDisposable(); var debounceDisposable = new SerialDisposable(); disposables.Add(debounceDisposable); Action debounce = () => { debounceDisposable.Disposable = scheduler.Schedule(dueTime, () => { var debouncedItem = itemSelector(); o.OnNext(debouncedItem); }); }; disposables.Add(source.Subscribe(x => { debounce(); o.OnNext(x); }, o.OnError, o.OnCompleted)); debounce(); return disposables; })); }
public static IDisposable Subscribe <T, TKey>(this IGroupedObservable <T, TKey> value, Action <T> onNext, Action <Exception> onError, Action onCompleted) { Observer <T> observer = new Observer <T>(onNext, onError, onCompleted); IDisposable subject = value.Subscribe(observer); return(subject); }
private IObservable <OrderBook> CombineWithSnapshot(IGroupedObservable <string, DepthUpdate> grouped) { // https://github.com/binance-exchange/binance-official-api-docs/blob/master/web-socket-streams.md#how-to-manage-a-local-order-book-correctly // // How to manage a local order book correctly // // Open a stream to wss://stream.binance.com:9443/ws/bnbbtc@depth // Buffer the events you receive from the stream // Get a depth snapshot from https://www.binance.com/api/v1/depth?symbol=BNBBTC&limit=1000 // Drop any event where u is <= lastUpdateId in the snapshot // The first processed should have U <= lastUpdateId+1 AND u >= lastUpdateId+1 // While listening to the stream, each new event's U should be equal to the previous event's u+1 // The data in each event is the absolute quantity for a price level // If the quantity is 0, remove the price level // Receiving an event that removes a price level that is not in your local order book can happen and is normal. return(Observable.FromAsync(async() => { var binanceOb = await _client.GetOrderBook(grouped.Key); return (binanceOb.LastUpdateId, binanceOb.ToOrderBook(grouped.Key)); }) .SelectMany(restOb => { var(seedUpdateId, seedOb) = restOb; return grouped .SkipWhile(x => x.LastUpdateId <= seedUpdateId) .Scan((seedUpdateId, seedOb, false), ApplyOrderBookUpdate) .Select(x => x.Item2); })); }
private void DropStream(IGroupedObservable <TKey, T> value) { lock (_guard) { IList <IGroupedObservable <TKey, T> > list; try { _streamList.Remove(value); list = new List <IGroupedObservable <TKey, T> >(_streamList); _seed = _aggregator(_seed, list); } catch (Exception ex) { _subject.OnError(ex); return; } /* Ensure Rx contract: Not to invoke observers concurrently. * Therefore, OnNext call is inside guard. */ _subject.OnNext(list); if (_completed) { _subject.OnCompleted(); } } }
/// <summary> /// Initializes a new instance of the <see cref="GroupedMonitored{TKey, TElement}" /> class. /// </summary> /// <param name="group">The group.</param> /// <param name="name">The name.</param> /// <param name="order">The order.</param> /// <param name="surrogate">The surrogate.</param> public GroupedMonitored( IGroupedObservable <TKey, TElement> group, string name, double order, Func <TElement, object> surrogate) { _key = group.Key; _groupStream = group.Monitor(name, order, surrogate); }
public void OnNext(IGroupedObservable <TKey, T> value) { AddStream(value); value.Subscribe(data => { /* OnNext = No-op */ }, ex => DropStream(value), () => DropStream(value)); }
/// <summary> /// Initializes a new instance of the <see cref="GroupedMonitored{TKey, TElement}" /> class. /// </summary> /// <param name="group">The group.</param> /// <param name="name">The name.</param> /// <param name="order">The order.</param> /// <param name="surrogate">The surrogate.</param> /// <param name="keywords">The keywords.</param> public GroupedMonitored( IGroupedObservable <TKey, TElement> group, string name, double order, IMonitorSurrogate <TElement> surrogate, params string[] keywords) { _key = group.Key; _groupStream = group.Monitor(name, order, surrogate, keywords); }
void IObserver <IGroupedObservable <int, int> > .OnNext(IGroupedObservable <int, int> value) { formItem.txtResult.AppendText("Key = " + value.Key + "(只处理 Key=0 的明细)"); formItem.txtResult.AppendText("\r\n"); if (value.Key == 0) { value // 观察者线程,跑到 WinForm 控件的线程上. .ObserveOn(this.formItem.uiScheduler) .Subscribe(this.formItem.myObserver); } }
private void ProcessMessage(IGroupedObservable <string, string> item, ILightsManager[] bridges) { item.SampleFirst(TimeSpan.FromSeconds(2), scheduler) .Select(button => OnMacMessage(bridges, button)) .Merge() .Subscribe( x => { log.Info("Command successful: {0}", x); }) ; }
private static void DumpGroup <T1, T2>(IGroupedObservable <T1, T2> seq) { Task.Factory.StartNew(() => { Console.Write($"Key={seq.Key}: "); var ev = new ManualResetEvent(false); using (var s = seq.Subscribe(a => DumpValue(a), () => ev.Set())) { ev.WaitOne(); } }); }
public static IObservable <Guid> DipsIntoTheRed (IGroupedObservable <Guid, Transaction> transactions) { Guid accountId = transactions.Key; decimal initialBalance = 0; var balance = transactions.Scan(initialBalance , (bal, trans) => bal + trans.Amount); return(from bal in balance.PairWithPrevious() where bal.Previous >= 0 && bal.Current < 0 select accountId); }
private IObservable <OrderBook> ProcessSingleInstrument( IGroupedObservable <string, IOrderBookMessage> currencyStream) { return(CombineWithSnapshot(currencyStream, currencyStream.Key) .Sample(TimeSpan.FromSeconds(5))); }
static IGroupedObservable <bool, long> DummyFunctionForTest(IGroupedObservable <bool, long> g) { Console.WriteLine($"Group: {g.Key}"); return(g); }