public async Task DeleteChatMessage(int id) { try { await _chatApiService.DeleteMessage(id); _chatsForUser.Edit(l => l.RemoveKey(id)); } catch (Exception ex) { _logger.Error(nameof(DeleteChatMessage), ex); throw; } }
private void EnumerateTaskBars() => _taskBarCache.Edit(i => { var taskBars = TaskBarWin32.EnumerateAllTaskBars(); i.Clear(); i.AddOrUpdate(taskBars); });
public LineScroller(FileInfo file, IObservable<ILineProvider> latest, IObservable<ScrollRequest> scrollRequest, ILogger logger, IScheduler scheduler = null) { if (file == null) throw new ArgumentNullException(nameof(file)); if (latest == null) throw new ArgumentNullException(nameof(latest)); if (logger == null) throw new ArgumentNullException(nameof(logger)); logger.Info($"Constructing file tailer for {file.FullName}"); var lines = new SourceCache<Line, LineKey>(l=>l.Key); Lines = lines.AsObservableCache(); var locker = new object(); scrollRequest = scrollRequest.Synchronize(locker); var aggregator = latest.CombineLatest(scrollRequest, (currentLines, scroll) => currentLines.ReadLines(scroll).ToArray()) .Subscribe(currentPage => { var previous = lines.Items.ToArray(); var added = currentPage.Except(previous,Line.TextStartComparer).ToArray(); var removed = previous.Except(currentPage, Line.TextStartComparer).ToArray(); lines.Edit(innerCache => { if (removed.Any()) innerCache.Remove(removed); if (added.Any()) innerCache.AddOrUpdate(added); }); }); _cleanUp = new CompositeDisposable(Lines, lines, aggregator); }
public CombinedSearchMetadataCollection([NotNull] ISearchMetadataCollection metadataCollection, [NotNull] IGlobalSearchOptions globalSearchOptions) { if (metadataCollection == null) { throw new ArgumentNullException(nameof(metadataCollection)); } if (globalSearchOptions == null) { throw new ArgumentNullException(nameof(globalSearchOptions)); } Local = metadataCollection; Global = globalSearchOptions.Metadata; var cache = new SourceCache <SearchMetadata, string>(t => t.SearchText); ////Prioritise local before global and renumber var localItems = metadataCollection.Metadata.Connect().ToCollection().Select(items => items.ToArray()).StartWith(Enumerable.Empty <SearchMetadata>()); var globalItems = globalSearchOptions.Metadata.Metadata.Connect().ToCollection().Select(items => items.ToArray()).StartWith(Enumerable.Empty <SearchMetadata>()); var combiner = localItems.CombineLatest(globalItems, (local, global) => new { local, global }).Select(x => Combine(x.local, x.global)).Subscribe(uppdatedItems => { cache.Edit(innerCache => { var toRemove = innerCache.Items.Except(uppdatedItems, SearchMetadata.SearchTextComparer).ToArray(); innerCache.Remove(toRemove); innerCache.AddOrUpdate(uppdatedItems); }); }); Combined = cache.Connect().IgnoreUpdateWhen((current, previous) => current.Equals(previous)).AsObservableCache(); _cleanUp = new CompositeDisposable(Combined, cache, combiner); }
public AppUserModelService(IUserApiService userApiService, ILogger logger, IAppSettings appSettings) { _favouriteCakes = new SourceCache <CakeDto, int>(c => c.Id); _appSettings = appSettings; _userIdSubject = new BehaviorSubject <string>(String.Empty); _userSubject = new BehaviorSubject <UserDto>(null); _cd = new CompositeDisposable(); _favouriteCakes .Connect() .CacheChangeSet(CacheKey, logger) .Subscribe(); _userIdSubject .ObserveOn(RxApp.TaskpoolScheduler) .Where(u => u != null) .SelectMany(async uId => await userApiService.GetFavourites(uId)) .RetryWithBackoff(3) .LogException(logger) .Subscribe(cakes => { _favouriteCakes.Edit(l => l.AddOrUpdate(cakes)); }) .DisposeWith(_cd); Observable.FromAsync(async() => await _favouriteCakes.FromCache(CacheKey, EqualityComparer <CakeDto> .Default)).Subscribe().DisposeWith(_cd); }
public static async Task <ServiceOperationResult> LoadDatabasesIntoSourceCache(SourceCache <Database, string> sourceCache) { var serviceOperationHelper = new ServiceOperationHelper(typeof(Database), Plurality.Plural, ServiceOperation.Load, _targetName); await Task.Run(() => { try { serviceOperationHelper.LogServiceOperation(ServiceOperationStatus.Attempting); sourceCache.Edit(innerCache => { foreach (var xmlDatabase in Settings.Default.XmlDatabases) { innerCache.AddOrUpdate(new Database(xmlDatabase, false)); } }); serviceOperationHelper.LogServiceOperation(ServiceOperationStatus.Succeeded); } catch (Exception ex) { serviceOperationHelper.LogServiceOperation(ex.Message); } }); return(serviceOperationHelper.ServiceOperationResult); }
public ChatModelService(IAppUserModelService appUserModelService, IChatApiService chatApiService, IBakerModelService bakerModelService, ILogger logger) { _chatApiService = chatApiService; _logger = logger; _chatsForUser = new SourceCache <ChatMessageDto, int>(cm => cm.Id); _bakerChatsForUser = new SourceCache <BakerDto, string>(bk => bk.Id); appUserModelService .UserObservable .ObserveOn(RxApp.TaskpoolScheduler) .Where(u => u != null) .SelectMany(async u => await chatApiService.GetChatsForUser(u.Id)) .RetryWithBackoff(3) .LogException(logger) .Subscribe(async chatMessages => { _chatsForUser.Edit(l => l.AddOrUpdate(chatMessages)); var bakerIds = chatMessages.GroupBy(cm => cm.BakerId).Select(b => b.Key); foreach (var bakerId in bakerIds) { var baker = await bakerModelService.GetBaker(bakerId); _bakerChatsForUser.Edit(l => l.AddOrUpdate(baker)); //TODO: optimize } }); }
public static async Task <ServiceOperationResult> LoadLogEntriesIntoSourceCacheAsync(LogFile logFile, SourceCache <LogEntry, string> logEntriesSourceCache) { var serviceOperationHelper = new ServiceOperationHelper(typeof(LogEntry), Plurality.Plural, ServiceOperation.Load, $"{typeof(LogFile).Name} with network path \"{logFile.NetworkFile.FullName}\""); await Task.Run(() => { try { serviceOperationHelper.LogServiceOperation(ServiceOperationStatus.Attempting); var numberOfOldLogEntries = logEntriesSourceCache.Keys.Where(k => k.Contains(logFile.Identifier)).Count(); var contents = File.ReadAllText(logFile.NetworkFile.FullName); long logEntryIndex = 0; logEntriesSourceCache.Edit(innerCache => { foreach (var line in GetLogEntriesFromLogContents(contents)) { if (++logEntryIndex > numberOfOldLogEntries) { var newLogEntry = ParseLogEntry(line, logFile, LogEntry.GetIdentifier(logFile.Identifier, logEntryIndex)); newLogEntry.IsNew = true; innerCache.AddOrUpdate(newLogEntry); } } }); serviceOperationHelper.LogServiceOperation(ServiceOperationStatus.Succeeded); } catch (Exception ex) { serviceOperationHelper.LogServiceOperation(ex.Message); } }); return(serviceOperationHelper.ServiceOperationResult); }
public CakeModelService( ICakeApiService cakeApiService, IAppUserModelService appUserModelService, IPaymentApiService paymentApiService, ILogger logger) { _cakeApiService = cakeApiService; _paymentApiService = paymentApiService; _nearbyCakes = new SourceCache <CakeDto, int>(c => c.Id); _cd = new CompositeDisposable(); //_nearbyCakes // .Connect() // .CacheChangeSet(_cacheKey, logger) // .Subscribe(); appUserModelService .UserObservable .ObserveOn(RxApp.TaskpoolScheduler) .Where(u => u != null) .SelectMany(async u => await cakeApiService.GetNearbyCakes(u.Position)) .RetryWithBackoff(3) .LogException(logger) .Subscribe(cakes => { _nearbyCakes.Edit(l => l.AddOrUpdate(cakes)); }); //Observable.FromAsync(async () => await _nearbyCakes.FromCache(_cacheKey, EqualityComparer<CakeDto>.Default)).Subscribe().DisposeWith(_cd); }
private void InitializeAvailableUsernamesAndComputernamesAsync() { Task.Run(() => { AvailableUsernamesSourceCache.Edit(innerCache => { innerCache.Clear(); innerCache.AddOrUpdate(string.Empty); }); AvailableComputernamesSourceCache.Edit(innerCache => { innerCache.Clear(); innerCache.AddOrUpdate(string.Empty); }); }); }
private async Task EditPerson(ParentWithChildren parentWithChildren) { //in a real world app you would pass _people in and allow the selectable items source to dynamically change var editor = new RelationEditor(parentWithChildren, _people.Items.ToArray()); //TODO: Investigate why selectable state is being held onto ny the Dialog await DialogHost.Show(editor, (object sender, DialogClosingEventArgs eventArgs) => { //use the .Edit method as it is more efficient when apply multiple changes _relations.Edit(innerCache => { //extract the new relations var newRelations = editor.Children .Where(c => c.IsSelected).Select(selectable => new Relation(parentWithChildren.Parent, (Person)selectable)) .ToArray(); //remove old ones var toRemove = innerCache .Items.Where(r => r.Parent == parentWithChildren.Parent && !newRelations.Contains(r)) .ToArray(); innerCache.Remove(toRemove); innerCache.AddOrUpdate(newRelations); }); }); }
public CombinedSearchMetadataCollection([NotNull] ISearchMetadataCollection metadataCollection, [NotNull] IGlobalSearchOptions globalSearchOptions) { if (metadataCollection == null) throw new ArgumentNullException(nameof(metadataCollection)); if (globalSearchOptions == null) throw new ArgumentNullException(nameof(globalSearchOptions)); Local = metadataCollection; Global = globalSearchOptions.Metadata; var cache = new SourceCache<SearchMetadata, string>(t => t.SearchText); ////Prioritise local before global and renumber var localItems = metadataCollection.Metadata.Connect().ToCollection().Select(items => items.ToArray()).StartWith(Enumerable.Empty<SearchMetadata>()); var globalItems = globalSearchOptions.Metadata.Metadata.Connect().ToCollection().Select(items => items.ToArray()).StartWith(Enumerable.Empty<SearchMetadata>()); var combiner = localItems.CombineLatest(globalItems, (local, global) => new {local, global}).Select(x => Combine(x.local, x.global)).Subscribe(uppdatedItems => { cache.Edit(innerCache => { var toRemove = innerCache.Items.Except(uppdatedItems,SearchMetadata.SearchTextComparer).ToArray(); innerCache.Remove(toRemove); innerCache.AddOrUpdate(uppdatedItems); }); }); Combined = cache.Connect().IgnoreUpdateWhen((current, previous) => current.Equals(previous)).AsObservableCache(); _cleanUp = new CompositeDisposable(Combined, cache, combiner); }
private void EnumerateWindows() => _monitorCache.Edit(i => { var currentMonitors = MonitorWin32.EnumerateDisplayMonitors(); i.Clear(); i.AddOrUpdate(currentMonitors); });
public LineScroller([NotNull] IObservable <ILineProvider> latest, [NotNull] IObservable <ScrollRequest> scrollRequest) { if (latest == null) { throw new ArgumentNullException(nameof(latest)); } if (scrollRequest == null) { throw new ArgumentNullException(nameof(scrollRequest)); } var lines = new SourceCache <Line, LineKey>(l => l.Key); Lines = lines.Connect().IgnoreUpdateWhen((current, previous) => current.Key == previous.Key).AsObservableCache(); var locker = new object(); scrollRequest = scrollRequest.Synchronize(locker); latest = latest.Synchronize(locker); var aggregator = latest .CombineLatest(scrollRequest, (currentLines, scroll) => new { currentLines, scroll }) .Sample(TimeSpan.FromMilliseconds(50)) .Select(x => { if (x.scroll == ScrollRequest.None || x.scroll.PageSize == 0 || x.currentLines.Count == 0) { return(new Line[0]); } return(x.currentLines.ReadLines(x.scroll).ToArray()); }) .RetryWithBackOff <Line[], Exception>((ex, i) => TimeSpan.FromSeconds(1)) .Subscribe(currentPage => { var previous = lines.Items.ToArray(); var added = currentPage.Except(previous, Line.TextStartComparer).ToArray(); var removed = previous.Except(currentPage, Line.TextStartComparer).ToArray(); lines.Edit(innerCache => { if (currentPage.Length == 0) { innerCache.Clear(); } if (removed.Any()) { innerCache.Remove(removed); } if (added.Any()) { innerCache.AddOrUpdate(added); } }); }); _cleanUp = new CompositeDisposable(Lines, lines, aggregator); }
public void AddOrUpdate(IEnumerable <IFileReference> fileReferences) { _cache.Edit(innerList => { innerList.Clear(); innerList.AddOrUpdate(fileReferences); }); }
public void Add(MyItem item) { //lock (locker) // uncomment to get rid of MissingKeyException { _sourceCache.Edit( updater => updater.AddOrUpdate(item), error => { Console.WriteLine(error); }); } }
public IObservable <Unit> LoadUpcomingMovies(int index) { return(_movieCache .GetAndFetchLatest($"upcoming_movies_{index}", () => FetchUpcomingMovies(index)) .Select(x => { _internalSourceCache.Edit(innerCache => innerCache.AddOrUpdate(x)); return Unit.Default; })); }
public StrategyService() { _availableEntitiesCache = new SourceCache <IStrategy, String>(price => price.EntityCacheKey); _availableEntities = _availableEntitiesCache.AsObservableCache(); _availableEntitiesCache.Edit(innerCache => { innerCache.AddOrUpdate(Enumerable.Range(0, 5).Select(_ => new Strategy())); }); }
public TicTacToeGame() { gameBoard = new SourceCache <Field, int>(f => f.PositionX * BOARD_SIZE + f.PositionY); gameBoard.Edit(c => c.AddOrUpdate( Enumerable.Range(0, BOARD_SIZE) .Select(row => Enumerable.Range(0, BOARD_SIZE) .Select(column => new Field(column, row))) .SelectMany(x => x))); }
public LineScroller([NotNull] IObservable <ILineProvider> latest, [NotNull] IObservable <ScrollRequest> scrollRequest) { if (latest == null) { throw new ArgumentNullException(nameof(latest)); } if (scrollRequest == null) { throw new ArgumentNullException(nameof(scrollRequest)); } var lines = new SourceCache <Line, LineKey>(l => l.Key); Lines = lines.AsObservableCache(); var locker = new object(); scrollRequest = scrollRequest.Synchronize(locker); latest = latest.Synchronize(locker); var aggregator = latest .CombineLatest(scrollRequest, (currentLines, scroll) => { try { return(currentLines.ReadLines(scroll).ToArray()); } catch (Exception ex) { throw ex; } }) .Subscribe(currentPage => { var previous = lines.Items.ToArray(); var added = currentPage.Except(previous, Line.TextStartComparer).ToArray(); var removed = previous.Except(currentPage, Line.TextStartComparer).ToArray(); lines.Edit(innerCache => { if (removed.Any()) { innerCache.Remove(removed); } if (added.Any()) { innerCache.AddOrUpdate(added); } }); }); _cleanUp = new CompositeDisposable(Lines, lines, aggregator); }
/// <summary> /// Smartly update the current cache with the specified list. /// </summary> /// <param name="offset"></param> /// <param name="items"></param> /// <param name="replaceAll"></param> protected override void AddUpdate(int offset, List <TItem> items, bool replaceAll = false) { _cache.Edit((c) => { if (replaceAll) { c.Clear(); } c.AddOrUpdate(items); }); }
public TradeTask(IEnumerable <OrderTrade> exchangeTrades = null) { Trades = new SourceCache <OrderTrade, string>(x => x.Id); Events = new Dictionary <DateTime, string>(); if (exchangeTrades != null) { Trades.Edit(innerList => innerList.AddOrUpdate(exchangeTrades)); } Jobs = new List <OrderTask>(); FinishedJobs = new Queue <OrderTask>(); Events = new Dictionary <DateTime, string>(); }
public LineScroller(FileInfo file, IObservable <ILineProvider> latest, IObservable <ScrollRequest> scrollRequest, ILogger logger, IScheduler scheduler = null) { if (file == null) { throw new ArgumentNullException(nameof(file)); } if (latest == null) { throw new ArgumentNullException(nameof(latest)); } if (logger == null) { throw new ArgumentNullException(nameof(logger)); } logger.Info($"Constructing file tailer for {file.FullName}"); var lines = new SourceCache <Line, LineKey>(l => l.Key); Lines = lines.AsObservableCache(); var locker = new object(); scrollRequest = scrollRequest.Synchronize(locker); var aggregator = latest.CombineLatest(scrollRequest, (currentLines, scroll) => currentLines.ReadLines(scroll).ToArray()) .RetryWithBackOff <Line[], Exception>((ex, i) => TimeSpan.FromSeconds(1)) .Subscribe(currentPage => { var previous = lines.Items.ToArray(); var added = currentPage.Except(previous, Line.TextStartComparer).ToArray(); var removed = previous.Except(currentPage, Line.TextStartComparer).ToArray(); lines.Edit(innerCache => { if (removed.Any()) { innerCache.Remove(removed); } if (added.Any()) { innerCache.AddOrUpdate(added); } }); }); _cleanUp = new CompositeDisposable(Lines, lines, aggregator); }
private void OnBatchEventReceived(IEnumerable <IEvent <TKey, TAggregate> > events) { //if the gate is down: //1) either we're caughting up, and thus using the _caughtingUpCache to keep the ongoing event stream //2) either we're not and we update the _sourceCache //if the gate is up, we're reconcialiting the _sourceCache with the _caughtingUpCache - hence, when the gate is down again IsCaughtingUp has been set to false and we update the _sourceCache _blockEventConsumption.Wait(); if (IsCaughtingUp) { _caughtingUpCache.CaughtUpEvents.AddRange(events); return; } ApplyEvents(events, (aggregates) => { _sourceCache.Edit((cache) => { cache.AddOrUpdate(aggregates); }); }); }
public void ErrorUpdatingStreamIsHandled() { bool completed = false; bool error = false; var cache = new SourceCache <ErrorInKey, int>(p => p.Key); var subscriber = cache.Connect().Finally(() => completed = true) .Subscribe(updates => { Console.WriteLine(); }); cache.Edit(updater => updater.AddOrUpdate(new ErrorInKey())); subscriber.Dispose(); error.Should().BeTrue(); completed.Should().BeTrue(); }
public void ErrorUpdatingStreamIsHandled() { bool completed = false; bool error = false; var cache = new SourceCache <ErrorInKey, int>(p => p.Key); var subscriber = cache.Connect().Finally(() => completed = true) .Subscribe(updates => { Console.WriteLine(); }); cache.Edit(updater => updater.AddOrUpdate(new ErrorInKey()), ex => error = true); subscriber.Dispose(); Assert.IsTrue(error, "Error has not been invoked"); Assert.IsTrue(completed, "Completed has not been called"); }
public async Task Initialise(int count = 5000) { await Task.Run(() => { _data.Edit(innerCache => { innerCache.Clear(); for (int i = 0; i < count; i++) { innerCache.AddOrUpdate(new Foo { Id = i, Title = $"Foo Number {i:0000}" }); } }); }); }
private void AddItems() { m_sourceCache.Edit(innerCache => { var list = new List <TestObject>(); for (var i = 0; i < 10; i++) { m_count++; list.Add(new TestObject() { Id = m_count, Group = i, Text = DateTime.Now.ToString("T") }); } innerCache.AddOrUpdate(list); }); }
public void Prueba1() { var myCache = new SourceCache <User, int>(t => t.Id); IObservable <IChangeSet <User, int> > myCacheSet = myCache.Connect(); myCacheSet.Filter(u => u.Id == 2); myCache.Edit(items => { items.Clear(); items.AddOrUpdate(new User { Id = 2, Name = "Sima" }); }); var myConnection = myCacheSet.ToObservableChangeSet(t => t.Key, expireAfter: item => TimeSpan.FromHours(1)); }
/*@" * SELECT * [SOADB].[dbo].[Local_SSI_ErrorLogDetail].[OBJECT_NAME], * [SOADB].[dbo].[Local_SSI_ErrorLogDetail].[Error_Section], * [SOADB].[dbo].[Local_SSI_ErrorLogDetail].[ERROR_MESSAGE], * [SOADB].[dbo].[Local_SSI_ErrorLogDetail].[TimeStamp], * [SOADB].[dbo].[Local_SSI_ErrorSeverityLevel].[Severity_Level_Desc] * FROM[SOADB].[dbo].[Local_SSI_ErrorLogDetail] * WITH (NOLOCK) * INNER JOIN [SOADB].[dbo].[Local_SSI_ErrorSeverityLevel] * ON[SOADB].[dbo].[Local_SSI_ErrorSeverityLevel].Severity_Level_Id = [SOADB].[dbo].[Local_SSI_ErrorLogDetail].Error_Severity_Level * ORDER BY [SOADB].[dbo].[Local_SSI_ErrorLogDetail].[TimeStamp]";*/ #endregion #region Public methods public static async Task <ServiceOperationResult> LoadLogEntriesIntoSourceCache(Database database, SourceCache <LogEntry, string> logEntriesSourceCache) { var serviceOperationHelper = new ServiceOperationHelper(typeof(LogEntry), Plurality.Plural, ServiceOperation.Load, $"{typeof(Database).Name} {database.Name}"); await Task.Run(() => { try { serviceOperationHelper.LogServiceOperation(ServiceOperationStatus.Attempting); var numberOfOldLogEntries = logEntriesSourceCache.Keys.Where(k => k.Contains(database.Identifier)).Count(); var addDatabaseInfo = new AddDatabaseInfo(database.Name); var sqlConnection = new SqlConnection(addDatabaseInfo.ToConnectionString()); sqlConnection.Open(); using (SqlCommand sqlCommand = new SqlCommand(GetSQLCommandText(addDatabaseInfo.DatabaseName), sqlConnection)) { using (var sqlDataReader = sqlCommand.ExecuteReader()) { long logEntryIndex = 0; logEntriesSourceCache.Edit(innerCache => { while (sqlDataReader.Read()) { if (++logEntryIndex > numberOfOldLogEntries) { //If the log entry is new var newLogEntry = ParseDatabaseLogEntry(sqlDataReader, database.Name, database, LogEntry.GetIdentifier(database.Identifier, logEntryIndex)); newLogEntry.IsNew = true; innerCache.AddOrUpdate(newLogEntry); } } }); } } sqlConnection.Close(); sqlConnection.Dispose(); serviceOperationHelper.LogServiceOperation(ServiceOperationStatus.Succeeded); } catch (Exception ex) { serviceOperationHelper.LogServiceOperation(ex.Message); } }); return(serviceOperationHelper.ServiceOperationResult); }
public void FilterError() { bool completed = false; bool error = false; var source = new SourceCache <TransformEntityWithError, int>(e => e.Key); var subscriber = source.Connect() .Filter(x => true) .Finally(() => completed = true) .Subscribe(updates => { Console.WriteLine(); }); source.Edit(updater => updater.AddOrUpdate(new TransformEntityWithError(new Entity())), ex => error = true); subscriber.Dispose(); Assert.IsTrue(error, "Error has not been invoked"); Assert.IsTrue(completed, "Completed has not been called"); }
public void FilterError() { bool completed = false; bool error = false; var source = new SourceCache <TransformEntityWithError, int>(e => e.Key); var subscriber = source.Connect() .Filter(x => true) .Finally(() => completed = true) .Subscribe(updates => { Console.WriteLine(); }); source.Edit(updater => updater.AddOrUpdate(new TransformEntityWithError(new Entity())), ex => error = true); subscriber.Dispose(); error.Should().BeTrue(); completed.Should().BeTrue(); }
public LineScroller([NotNull] IObservable<ILineProvider> latest, [NotNull] IObservable<ScrollRequest> scrollRequest) { if (latest == null) throw new ArgumentNullException(nameof(latest)); if (scrollRequest == null) throw new ArgumentNullException(nameof(scrollRequest)); var lines = new SourceCache<Line, LineKey>(l => l.Key); Lines = lines.AsObservableCache(); var locker = new object(); scrollRequest = scrollRequest.Synchronize(locker); latest = latest.Synchronize(locker); var aggregator = latest .CombineLatest(scrollRequest, (currentLines, scroll) => { try { var x = currentLines.ReadLines(scroll).ToArray(); return x; } catch (Exception ex) { throw ex; } }) .Subscribe(currentPage => { var previous = lines.Items.ToArray(); var added = currentPage.Except(previous, Line.TextStartComparer).ToArray(); var removed = previous.Except(currentPage, Line.TextStartComparer).ToArray(); lines.Edit(innerCache => { if (removed.Any()) innerCache.Remove(removed); if (added.Any()) innerCache.AddOrUpdate(added); }); }); _cleanUp = new CompositeDisposable(Lines, lines, aggregator); }
public void ErrorUpdatingStreamIsHandled() { bool completed = false; bool error = false; var cache = new SourceCache<ErrorInKey, int>(p=>p.Key); var subscriber = cache.Connect().Finally(() => completed = true) .Subscribe(updates => { Console.WriteLine(); }); cache.Edit(updater => updater.AddOrUpdate(new ErrorInKey()),ex=> error=true); subscriber.Dispose(); Assert.IsTrue(error, "Error has not been invoked"); Assert.IsTrue(completed, "Completed has not been called"); }
public void FilterError() { bool completed = false; bool error = false; var source = new SourceCache<TransformEntityWithError, int>(e=>e.Key); var subscriber = source.Connect() .Filter(x=>true) .Finally(() => completed = true) .Subscribe(updates => { Console.WriteLine(); }); source.Edit(updater => updater.AddOrUpdate(new TransformEntityWithError(new Entity())), ex => error = true); subscriber.Dispose(); Assert.IsTrue(error, "Error has not been invoked"); Assert.IsTrue(completed, "Completed has not been called"); }
public LineScroller([NotNull] IObservable<ILineProvider> latest, [NotNull] IObservable<ScrollRequest> scrollRequest) { if (latest == null) throw new ArgumentNullException(nameof(latest)); if (scrollRequest == null) throw new ArgumentNullException(nameof(scrollRequest)); var lines = new SourceCache<Line, LineKey>(l => l.Key); Lines = lines.AsObservableCache(); var locker = new object(); scrollRequest = scrollRequest.Synchronize(locker); latest = latest.Synchronize(locker); var aggregator = latest .CombineLatest(scrollRequest, (currentLines, scroll) => new { currentLines, scroll}) .Sample(TimeSpan.FromMilliseconds(50)) .Select(x => { if (x.scroll.PageSize == 0 || x.currentLines.Count == 0) return new Line[0]; return x.currentLines.ReadLines(x.scroll).ToArray(); }) .Subscribe(currentPage => { var previous = lines.Items.ToArray(); var added = currentPage.Except(previous, Line.TextStartComparer).ToArray(); var removed = previous.Except(currentPage, Line.TextStartComparer).ToArray(); lines.Edit(innerCache => { if (removed.Any()) innerCache.Remove(removed); if (added.Any()) innerCache.AddOrUpdate(added); }); }); _cleanUp = new CompositeDisposable(Lines, lines, aggregator); }