public SqlitePersistentBlobCache(string databaseFile, IScheduler scheduler = null, IServiceProvider serviceProvider = null) { Scheduler = scheduler ?? RxApp.TaskpoolScheduler; ServiceProvider = serviceProvider; BlobCache.EnsureInitialized(); _connection = new SQLiteAsyncConnection(databaseFile, storeDateTimeAsTicks: true); _connection.CreateTableAsync <CacheElement>(); _inflightCache = new MemoizingMRUCache <string, IObservable <CacheElement> >((key, ce) => { return(_connection.QueryAsync <CacheElement>("SELECT * FROM CacheElement WHERE Key=? LIMIT 1;", key) .SelectMany(x => { return (x.Count == 1) ? Observable.Return(x[0]) : ObservableThrowKeyNotFoundException(key); }) .SelectMany(x => { if (x.Expiration < Scheduler.Now.UtcDateTime) { return Invalidate(key).SelectMany(_ => ObservableThrowKeyNotFoundException(key)); } else { return Observable.Return(x); } })); }, 10); }
public CalculatorViewModel() { _cache = new MemoizingMRUCache <int, int>((x, ctx) => { Thread.Sleep(1000); // Pretend this calculation isn’t cheap return(x * 10); }, 5); CalculateCommand = new ReactiveCommand(this.WhenAny(x => x.Number, x => x.Value > 0)); (CalculateCommand as ReactiveCommand).RegisterAsyncTask(o => { return(Task.Factory.StartNew(() => { int top; bool cached = _cache.TryGet(Number, out top); if (cached) { Result = 0; Thread.Sleep(1000); Result = top; } else { top = _cache.Get(Number); for (int i = 0; i <= top; i++) { Result = i; Thread.Sleep(100); } } })); }); }
static KVOObservableForProperty() { var monotouchAssemblyName = typeof(NSObject).Assembly.FullName; declaredInNSObject = new MemoizingMRUCache<Tuple<Type, string>, bool>((pair, _) => { var thisType = pair.Item1; // Types that aren't NSObjects at all are uninteresting to us if (typeof(NSObject).IsAssignableFrom(thisType) == false) { return false; } while(thisType != null) { if (thisType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Any(x => x.Name == pair.Item2)) { // NB: This is a not-completely correct way to detect if // an object is defined in an Obj-C class (it will fail if // you're using a binding to a 3rd-party Obj-C library). return thisType.Assembly.FullName == monotouchAssemblyName; } thisType = thisType.BaseType; } // The property doesn't exist at all return false; }, RxApp.BigCacheLimit); }
static KVOObservableForProperty() { var monotouchAssemblyName = typeof(NSObject).Assembly.FullName; declaredInNSObject = new MemoizingMRUCache <Tuple <Type, string>, bool>((pair, _) => { var thisType = pair.Item1; // Types that aren't NSObjects at all are uninteresting to us if (typeof(NSObject).IsAssignableFrom(thisType) == false) { return(false); } while (thisType != null) { if (thisType.GetMembers(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly).Any(x => x.Name == pair.Item2)) { // NB: This is a not-completely correct way to detect if // an object is defined in an Obj-C class (it will fail if // you're using a binding to a 3rd-party Obj-C library). return(thisType.Assembly.FullName == monotouchAssemblyName); } thisType = thisType.BaseType; } // The property doesn't exist at all return(false); }, RxApp.BigCacheLimit); }
public CalculatorViewModel() { _reactiveHelper = new MakeObjectReactiveHelper(this); _cache = new MemoizingMRUCache<int, int>((x, ctx) => { Thread.Sleep(1000); // Pretend this calculation isn’t cheap return x*10; }, 5); CalculateCommand = new ReactiveAsyncCommand(this.WhenAny(x => x.Number, x => x.Value > 0)); (CalculateCommand as ReactiveAsyncCommand).RegisterAsyncTask<object>(o => { return Task.Factory.StartNew(() => { int top; bool cached = _cache.TryGet( Number, out top); if (cached) { Result = 0; Thread.Sleep(1000); Result = top; } else { top = _cache.Get(Number); for (int i = 0; i <= top; i++) { Result = i; Thread.Sleep(100); } } }); }); }
protected PersistentBlobCache(string cacheDirectory = null, IFilesystemProvider filesystemProvider = null, IScheduler scheduler = null) { this.CacheDirectory = cacheDirectory ?? GetDefaultRoamingCacheDirectory(); this.Scheduler = scheduler ?? RxApp.TaskpoolScheduler; this.filesystem = filesystemProvider ?? new SimpleFilesystemProvider(); // Here, we're not actually caching the requests directly (i.e. as // byte[]s), but as the "replayed result of the request", in the // AsyncSubject - this makes the code infinitely simpler because // we don't have to keep a separate list of "in-flight reads" vs // "already completed and cached reads" MemoizedRequests = new MemoizingMRUCache<string, AsyncSubject<byte[]>>( (x, c) => FetchOrWriteBlobFromDisk(x, c, false), 20); try { var dir = filesystem.CreateRecursive(CacheDirectory); #if WINRT // NB: I don't want to talk about it. dir.Wait(); #endif } catch (Exception ex) { this.Log().FatalException("Couldn't create cache directory", ex); } var cacheIndex = FetchOrWriteBlobFromDisk(BlobCacheIndexKey, null, true) .Catch(Observable.Return(new byte[0])) .Select(x => Encoding.UTF8.GetString(x, 0, x.Length).Split('\n') .SelectMany(ParseCacheIndexEntry) .ToDictionary(y => y.Key, y => y.Value)) .Select(x => new ConcurrentDictionary<string, CacheIndexEntry>(x)); #if WINRT CacheIndex = cacheIndex.First(); #else cacheIndex.Subscribe(x => CacheIndex = x); #endif flushThreadSubscription = Disposable.Empty; if (!RxApp.InUnitTestRunner()) { flushThreadSubscription = actionTaken .Where(_ => CacheIndex != null) .Throttle(TimeSpan.FromSeconds(30), Scheduler) .SelectMany(_ => FlushCacheIndex(true)) .Subscribe(_ => { this.Log().Debug("Flushing cache"); lastFlushTime = Scheduler.Now; }); } this.Log().Info("{0} entries in blob cache index", CacheIndex.Count); }
/// <summary> /// Initializes a new instance of the <see cref="FragmentationSequence"/> class. /// </summary> /// <param name="sequence">The underlying sequence.</param> /// <param name="charge">Charge of sequence.</param> /// <param name="lcms">The LCMSRun for the data set.</param> /// <param name="activationMethod">The Activation Method.</param> public FragmentationSequence(Sequence sequence, int charge, ILcMsRun lcms, ActivationMethod activationMethod) { cacheLock = new object(); fragmentCache = new MemoizingMRUCache <Tuple <Composition, IonType>, LabeledIonViewModel>(GetLabeledIonViewModel, 1000); Sequence = sequence; Charge = charge; LcMsRun = lcms; ActivationMethod = activationMethod; }
public InMemoryCache() { _cache = new MemoizingMRUCache<string, CompilationResult>((file, _) => { Func<string, CompilationResult> compiler = null; lock (_delegateIndex) { compiler = _delegateIndex[file]; } return compiler(file); }, 50); }
public InMemoryCache() { _cache = new MemoizingMRUCache <string, object>((file, _) => { Func <string, object> compiler = null; lock (_delegateIndex) { compiler = _delegateIndex[file]; } return(compiler(file)); }, 50); }
public PersistentBlobCache( string cacheDirectory = null, IFilesystemProvider filesystemProvider = null, IScheduler scheduler = null, Action <AsyncSubject <byte[]> > invalidateCallback = null) { BlobCache.EnsureInitialized(); this.filesystem = filesystemProvider ?? Locator.Current.GetService <IFilesystemProvider>(); if (this.filesystem == null) { throw new Exception("No IFilesystemProvider available. This should never happen, your DependencyResolver is broken"); } this.CacheDirectory = cacheDirectory ?? filesystem.GetDefaultRoamingCacheDirectory(); this.Scheduler = scheduler ?? BlobCache.TaskpoolScheduler; // Here, we're not actually caching the requests directly (i.e. as // byte[]s), but as the "replayed result of the request", in the // AsyncSubject - this makes the code infinitely simpler because // we don't have to keep a separate list of "in-flight reads" vs // "already completed and cached reads" memoizedRequests = new MemoizingMRUCache <string, AsyncSubject <byte[]> >( (x, c) => FetchOrWriteBlobFromDisk(x, c, false), 20, invalidateCallback); var cacheIndex = FetchOrWriteBlobFromDisk(BlobCacheIndexKey, null, true) .Catch(Observable.Return(new byte[0])) .Select(x => Encoding.UTF8.GetString(x, 0, x.Length).Split('\n') .SelectMany(ParseCacheIndexEntry) .ToDictionary(y => y.Key, y => y.Value)) .Select(x => new ConcurrentDictionary <string, CacheIndexEntry>(x)); cacheIndex.Subscribe(x => CacheIndex = x); flushThreadSubscription = Disposable.Empty; if (!ModeDetector.InUnitTestRunner()) { flushThreadSubscription = actionTaken .Where(_ => CacheIndex != null) .Throttle(TimeSpan.FromSeconds(30), Scheduler) .SelectMany(_ => FlushCacheIndex(true)) .Subscribe(_ => this.Log().Debug("Flushing cache")); } this.Log().Info("{0} entries in blob cache index", CacheIndex.Count); }
public PersistentBlobCache( string cacheDirectory = null, IFilesystemProvider filesystemProvider = null, IScheduler scheduler = null, Action<AsyncSubject<byte[]>> invalidateCallback = null) { BlobCache.EnsureInitialized(); this.filesystem = filesystemProvider ?? Locator.Current.GetService<IFilesystemProvider>(); if (this.filesystem == null) { throw new Exception("No IFilesystemProvider available. This should never happen, your DependencyResolver is broken"); } this.CacheDirectory = cacheDirectory ?? filesystem.GetDefaultRoamingCacheDirectory(); this.Scheduler = scheduler ?? BlobCache.TaskpoolScheduler; // Here, we're not actually caching the requests directly (i.e. as // byte[]s), but as the "replayed result of the request", in the // AsyncSubject - this makes the code infinitely simpler because // we don't have to keep a separate list of "in-flight reads" vs // "already completed and cached reads" memoizedRequests = new MemoizingMRUCache<string, AsyncSubject<byte[]>>( (x, c) => FetchOrWriteBlobFromDisk(x, c, false), 20, invalidateCallback); var cacheIndex = FetchOrWriteBlobFromDisk(BlobCacheIndexKey, null, true) .Catch(Observable.Return(new byte[0])) .Select(x => Encoding.UTF8.GetString(x, 0, x.Length).Split('\n') .SelectMany(ParseCacheIndexEntry) .ToDictionary(y => y.Key, y => y.Value)) .Select(x => new ConcurrentDictionary<string, CacheIndexEntry>(x)); cacheIndex.Subscribe(x => CacheIndex = x); flushThreadSubscription = Disposable.Empty; if (!ModeDetector.InUnitTestRunner()) { flushThreadSubscription = actionTaken .Where(_ => CacheIndex != null) .Throttle(TimeSpan.FromSeconds(30), Scheduler) .SelectMany(_ => FlushCacheIndex(true)) .Subscribe(_ => this.Log().Debug("Flushing cache")); } this.Log().Info("{0} entries in blob cache index", CacheIndex.Count); }
public void TestCacheWithSingleKey() { var results = new List <int>(); var cache = new MemoizingMRUCache <Composition, int>((a, b) => { results.Add(0); return(0); }, 10); var composition = new Composition(3, 6, 0, 0, 0); Assert.True(results.Count == 0); cache.Get(composition); Assert.True(results.Count == 1); var composition2 = new Composition(3, 6, 0, 0, 0); cache.Get(composition2); Assert.True(results.Count == 1); }
/// <summary> /// Initializes a new instance of the <see cref="LabeledIonViewModel"/> class. /// </summary> /// <param name="composition">The empirical formula for this ion.</param> /// <param name="ionType">The fragment IonType for this ion.</param> /// <param name="isFragmentIon">A value indicating whether this ion is a fragment ion.</param> /// <param name="lcms">The LCMSRun for the data set that the ion is part of.</param> /// <param name="precursorIon">The precursor ion if this is a fragment ion.</param> /// <param name="isChargeState"> /// A value indicating whether this ion is a neighboring charge state to another /// precursor ion. /// </param> /// <param name="index">The index of this ion.</param> public LabeledIonViewModel(Composition composition, IonType ionType, bool isFragmentIon, ILcMsRun lcms, Ion precursorIon = null, bool isChargeState = false, int index = 0) { Composition = composition; PrecursorIon = precursorIon; Index = index; IonType = ionType; IsFragmentIon = isFragmentIon; IsChargeState = isChargeState; selected = true; xicCacheLock = new object(); peakCacheLock = new object(); peakCache = new MemoizingMRUCache <Tuple <Spectrum, bool>, IList <PeakDataPoint> >(GetPeakDataPoints, 5); xicCache = new MemoizingMRUCache <int, IList <XicDataPoint> >(GetXic, 10); Lcms = lcms; }
public MainView() { InitializeComponent(); // this is our cache of WPF brushes. Notice we're only allowing for 2 brushes to be cached this.brushes = new MemoizingMRUCache <Color, WPF.Brush>( this.CreateBrush, 2, _ => this.ViewModel.ResourcesReleased += 1); this .WhenActivated( disposables => { // make sure cache is invalidated whenever our data resets this .WhenAnyObservable(x => x.ViewModel.Reset) .Do(_ => this.brushes.InvalidateAll()) .Subscribe() .DisposeWith(disposables); this .OneWayBind(this.ViewModel, x => x.Dinosaurs, x => x.dinosaursListView.ItemsSource) .DisposeWith(disposables); this .OneWayBind(this.ViewModel, x => x.ColorKeys, x => x.colorKeyItemsControl.ItemsSource) .DisposeWith(disposables); this .Bind(this.ViewModel, x => x.IsCachingEnabled, x => x.isCachingEnabledCheckBox.IsChecked) .DisposeWith(disposables); this .Bind(this.ViewModel, x => x.IsDataOrderCacheFriendly, x => x.isDataOrderCacheFriendlyCheckBox.IsChecked) .DisposeWith(disposables); this .Bind(this.ViewModel, x => x.IsFakeDelayImposed, x => x.isFakeDelayImposedCheckBox.IsChecked) .DisposeWith(disposables); this .OneWayBind(this.ViewModel, x => x.ResourcesRequested, x => x.resourcesRequestedRun.Text) .DisposeWith(disposables); this .OneWayBind(this.ViewModel, x => x.ResourcesCreated, x => x.resourcesCreatedRun.Text) .DisposeWith(disposables); this .OneWayBind(this.ViewModel, x => x.ResourcesReleased, x => x.resourcesReleasedRun.Text) .DisposeWith(disposables); }); }
public void Dispose() { // We need to make sure that all outstanding writes are flushed // before we bail AsyncSubject <byte[]>[] requests; if (MemoizedRequests == null) { return; } lock (MemoizedRequests) { var mq = Interlocked.Exchange(ref MemoizedRequests, null); if (mq == null) { return; } requests = mq.CachedValues().ToArray(); MemoizedRequests = null; actionTaken.OnCompleted(); flushThreadSubscription.Dispose(); } IObservable <byte[]> requestChain = null; if (requests.Length > 0) { // Since these are all AsyncSubjects, most of them will replay // immediately, except for the ones still outstanding; we'll // Merge them all then wait for them all to complete. requestChain = requests.Merge(System.Reactive.Concurrency.Scheduler.Immediate) .Timeout(TimeSpan.FromSeconds(30), Scheduler) .Aggregate((acc, x) => x); } requestChain = requestChain ?? Observable.Return(new byte[0]); requestChain.SelectMany(FlushCacheIndex(true)).Subscribe(_ => { }); disposed = true; }
internal static void Shutdown() { lock (Locker) { Factory2D?.Dispose(); Device2D?.Dispose(); Brushes.InvalidateAll(); Brushes = null; DirectWriteFactory?.Dispose(); ImagingFactory?.Dispose(); Factory.Dispose(); Device.Dispose(); DeviceDebug?.Dispose(); DxgiDevice?.Dispose(); Shaders.DisposeAll(); } }
public CalculatorViewModel() { _cache = new MemoizingMRUCache<int, int>((x, ctx) => { Thread.Sleep(1000); // Pretend this calculation isn’t cheap return x*10; }, 5); CalculateCommand = ReactiveCommand.CreateAsyncTask<object>( this.WhenAnyValue(x => x.Number, x => x > 0), o => { return Task<object>.Factory.StartNew(() => { int top; bool cached = _cache.TryGet( Number, out top); if (cached) { Result = 0; Thread.Sleep(1000); Result = top; } else { top = _cache.Get(Number); for (int i = 0; i <= top; i++) { Result = i; Thread.Sleep(100); } } return null; }); }, RxApp.MainThreadScheduler); }
protected PersistentBlobCache(string cacheDirectory = null, IFilesystemProvider filesystemProvider = null, IScheduler scheduler = null) { this.CacheDirectory = cacheDirectory ?? GetDefaultRoamingCacheDirectory(); this.Scheduler = scheduler ?? RxApp.TaskpoolScheduler; this.filesystem = filesystemProvider ?? new SimpleFilesystemProvider(); // Here, we're not actually caching the requests directly (i.e. as // byte[]s), but as the "replayed result of the request", in the // AsyncSubject - this makes the code infinitely simpler because // we don't have to keep a separate list of "in-flight reads" vs // "already completed and cached reads" MemoizedRequests = new MemoizingMRUCache <string, AsyncSubject <byte[]> >( (x, c) => FetchOrWriteBlobFromDisk(x, c, false), 20); filesystem.CreateRecursive(CacheDirectory); FetchOrWriteBlobFromDisk(BlobCacheIndexKey, null, true) .Catch(Observable.Return(new byte[0])) .Select(x => Encoding.UTF8.GetString(x, 0, x.Length).Split('\n') .SelectMany(ParseCacheIndexEntry) .ToDictionary(y => y.Key, y => y.Value)) .Select(x => new ConcurrentDictionary <string, CacheIndexEntry>(x)) .Subscribe(x => CacheIndex = x); flushThreadSubscription = Disposable.Empty; if (!RxApp.InUnitTestRunner()) { flushThreadSubscription = actionTaken .Where(_ => CacheIndex != null) .Throttle(TimeSpan.FromSeconds(30), Scheduler) .SelectMany(_ => FlushCacheIndex(true)) .Subscribe(_ => { log.Debug("Flushing cache"); lastFlushTime = Scheduler.Now; }); } log.Info("{0} entries in blob cache index", CacheIndex.Count); }
public MainViewModel() { IsInProgress = Visibility.Collapsed; LoginCommand = new ReactiveAsyncCommand(this.WhenAny(t => t.UserName, t => t.Password, (x, y) => !string.IsNullOrEmpty(x.Value) && !string.IsNullOrEmpty(y.Value))); LoginCommand.ItemsInflight.Select(x => x > 0 ? Visibility.Visible : Visibility.Collapsed).Subscribe(x => IsInProgress = x); LoginCommand.RegisterAsyncFunction(_ => _gitHubService.Login(UserName, Password)).Subscribe( u => LoggedInUser = u); this.ObservableForProperty(x => x.LoggedInUser, user => user == null ? Visibility.Hidden : Visibility.Visible).Subscribe(v => IsUserLoggedIn = v); _cache = new MemoizingMRUCache<User, Repository[]>((user,_) => _gitHubService.GetRepositories(user), 3); this.WhenAny(t => t.LoggedInUser, u => u.Value != null).Where(filter => filter).Subscribe(_ => Repositories = new ReactiveCollection<Repository>(_cache.Get(LoggedInUser)) ); }
public CalculatorViewModel() { _cache = new MemoizingMRUCache <int, int>((x, ctx) => { Thread.Sleep(1000); // Pretend this calculation isn’t cheap return(x * 10); }, 5); CalculateCommand = ReactiveCommand.CreateAsyncTask <object>( this.WhenAnyValue(x => x.Number, x => x > 0), o => { return(Task <object> .Factory.StartNew(() => { int top; bool cached = _cache.TryGet(Number, out top); if (cached) { Result = 0; Thread.Sleep(1000); Result = top; } else { top = _cache.Get(Number); for (int i = 0; i <= top; i++) { Result = i; Thread.Sleep(100); } } return null; })); }, RxApp.MainThreadScheduler); }
public MainViewModel() { IsInProgress = Visibility.Collapsed; LoginCommand = new ReactiveAsyncCommand(this.WhenAny(t => t.UserName, t => t.Password, (x, y) => !string.IsNullOrEmpty(x.Value) && !string.IsNullOrEmpty(y.Value))); LoginCommand.ItemsInflight.Select(x => x > 0 ? Visibility.Visible : Visibility.Collapsed).Subscribe(x => IsInProgress = x); LoginCommand.RegisterAsyncFunction(_ => _gitHubService.Login(UserName, Password)).Subscribe( u => LoggedInUser = u); this.ObservableForProperty(x => x.LoggedInUser, user => user == null ? Visibility.Hidden : Visibility.Visible).Subscribe(v => IsUserLoggedIn = v); _cache = new MemoizingMRUCache <User, Repository[]>((user, _) => _gitHubService.GetRepositories(user), 3); this.WhenAny(t => t.LoggedInUser, u => u.Value != null).Where(filter => filter).Subscribe(_ => Repositories = new ReactiveCollection <Repository>(_cache.Get(LoggedInUser)) ); }
public void TestCacheWithTupleKey() { var results = new List <int>(); var cache = new MemoizingMRUCache <Tuple <Composition, IonType>, int>((a, b) => { results.Add(0); return(0); }, 10); var ionTypeFactory = new IonTypeFactory(10); var composition = new Composition(3, 6, 0, 0, 0); var ionType = ionTypeFactory.GetIonType("b"); var tuple = new Tuple <Composition, IonType>(composition, ionType); Assert.True(results.Count == 0); cache.Get(tuple); Assert.True(results.Count == 1); var tuple2 = new Tuple <Composition, IonType>(composition, ionType); cache.Get(tuple2); Assert.True(results.Count == 1); }
public CalculatorViewModel() { _cache = new MemoizingMRUCache<int, int>((x, ctx) => { Thread.Sleep(1000); // Pretend this calculation isn’t cheap return x*10; }, 5); CalculateCommand = ReactiveCommand.CreateAsyncTask(o => { return Task.Factory.StartNew(() => { int top; bool cached = _cache.TryGet( Number, out top); if (cached) { Result = 0; Thread.Sleep(1000); Result = top; } else { top = _cache.Get(Number); for (int i = 0; i <= top; i++) { Result = i; Thread.Sleep(100); } } }); }); }
internal static void Init() { Logger.Info("GraphicsManager initializing."); // Direct3D11 Init --- ResizeNextFrame = true; Factory = new FactoryDXGI(); ImagingFactory = new FactoryWIC(); Factory2D = new FactoryD2D(FactoryType.MultiThreaded, Engine.IsDebug ? DebugLevel.Error : DebugLevel.None); DirectWriteFactory = new FactoryDW(SharpDX.DirectWrite.FactoryType.Shared); CreateDevices(RenderSettings.GraphicsAdapter); Brushes = new MemoizingMRUCache <Colour, SolidColorBrush>( (colour, _) => new SolidColorBrush(Context2D, (Color4)colour) { Opacity = colour.A }, int.MaxValue, brush => brush.Dispose()); // ------------------------------------ Engine.HandleSet += hwnd => { var camera = Game.Workspace.CurrentCamera; camera.RenderHandle = hwnd; }; if (Engine.Handle != IntPtr.Zero) { var camera = Game.Workspace.CurrentCamera; camera.RenderHandle = Engine.Handle; } SamplerStates.Load(); Shaders.Init(); BlendStates.Load(); DepthStencilStates.Load(); RasterizerStates.Load(); //StandardConstants = new ConstantBuffer<StandardConstantData>(); StandardShader = Shaders.Get("Standard"); MainPass = StandardShader.GetPass(); LightingShader = Shaders.Get("Lighting"); LightingPass = LightingShader.GetPass(); PostProcessShader = Shaders.Get("PostProcess"); SkyboxShader = Shaders.Get("Skybox"); SkyboxPass = SkyboxShader.GetPass(); AdornShader = Shaders.Get("Adorn"); AALinePass = AdornShader.GetPass("AALine"); AdornSelfLitPass = AdornShader.GetPass("AdornSelfLit"); Shadows.Init(); // ------------------ IsInitialized = true; Initialized?.Invoke(); Initialized = null; //PixHelper.AllowProfiling(Engine.IsDebug); Logger.Info("Renderer initialized."); }
/// <summary> /// Initializes a new instance of the <see cref="IonListViewModel"/> class. /// </summary> /// <param name="lcms">The LCMSRun for the data set.</param> public IonListViewModel(ILcMsRun lcms) { prefixCompositionCache = new MemoizingMRUCache <Sequence, Composition[]>(GetPrefixCompositions, 20); suffixCompositionCache = new MemoizingMRUCache <Sequence, Composition[]>(GetSuffixCompositions, 20); this.lcms = lcms; fragmentCache = new MemoizingMRUCache <Tuple <Composition, IonType>, LabeledIonViewModel>(GetLabeledIonViewModel, 1000); cacheLock = new object(); IonTypes = new ReactiveList <IonType>(); ShowHeavy = false; FragmentLabels = new ReactiveList <LabeledIonViewModel>(); HeavyFragmentLabels = new ReactiveList <LabeledIonViewModel>(); PrecursorLabels = new ReactiveList <LabeledIonViewModel>(); HeavyPrecursorLabels = new ReactiveList <LabeledIonViewModel>(); ChargePrecursorLabels = new ReactiveList <LabeledIonViewModel>(); IsotopePrecursorLabels = new ReactiveList <LabeledIonViewModel>(); var precursorObservable = this.WhenAnyValue(x => x.SelectedPrSm, x => x.ShowHeavy).Where(x => x.Item1 != null); precursorObservable.Select(x => x.Item2 ? IcParameters.Instance.LightModifications : null) .SelectMany(async mods => await GenerateChargeLabelsAsync(mods)) .Subscribe(labels => ChargePrecursorLabels = labels); precursorObservable.Select(x => x.Item2 ? IcParameters.Instance.LightModifications : null) .SelectMany(async mods => await GenerateIsotopeLabelsAsync(mods)) .Subscribe(labels => { IsotopePrecursorLabels.ChangeTrackingEnabled = false; IsotopePrecursorLabels = labels; }); precursorObservable.Where(x => x.Item2) .SelectMany(async x => PrecursorViewMode == PrecursorViewMode.Isotopes ? await GenerateIsotopeLabelsAsync(IcParameters.Instance.HeavyModifications) : await GenerateChargeLabelsAsync(IcParameters.Instance.HeavyModifications)) .Subscribe(labels => { HeavyPrecursorLabels.ChangeTrackingEnabled = false; HeavyPrecursorLabels = labels; }); IcParameters.Instance.WhenAnyValue(x => x.PrecursorRelativeIntensityThreshold, x => x.LightModifications) .Where(_ => SelectedPrSm != null).Select(x => ShowHeavy ? x.Item2 : null) .SelectMany(async mods => await GenerateChargeLabelsAsync(mods)) .Subscribe(labels => { ChargePrecursorLabels.ChangeTrackingEnabled = false; ChargePrecursorLabels = labels; }); IcParameters.Instance.WhenAnyValue(x => x.PrecursorRelativeIntensityThreshold, x => x.LightModifications) .Where(_ => SelectedPrSm != null).Select(x => ShowHeavy ? x.Item2 : null) .SelectMany(async mods => await GenerateIsotopeLabelsAsync(mods)) .Subscribe(labels => { IsotopePrecursorLabels.ChangeTrackingEnabled = false; IsotopePrecursorLabels = labels; }); IcParameters.Instance.WhenAnyValue(x => x.PrecursorRelativeIntensityThreshold, x => x.HeavyModifications) .Where(_ => SelectedPrSm != null && ShowHeavy) .SelectMany(async x => PrecursorViewMode == PrecursorViewMode.Isotopes ? await GenerateIsotopeLabelsAsync(x.Item2) : await GenerateChargeLabelsAsync(x.Item2)) .Subscribe(labels => { HeavyPrecursorLabels.ChangeTrackingEnabled = false; HeavyPrecursorLabels = labels; }); this.WhenAnyValue(x => x.IsotopePrecursorLabels, x => x.ChargePrecursorLabels, x => x.PrecursorViewMode) .Select(x => x.Item3 == PrecursorViewMode.Isotopes ? x.Item1 : x.Item2) .Subscribe(labels => PrecursorLabels = labels); var fragmentObservable = this.WhenAnyValue(x => x.SelectedPrSm, x => x.IonTypes, x => x.ShowHeavy) .Where(x => x.Item1 != null) .Throttle(TimeSpan.FromMilliseconds(50), RxApp.TaskpoolScheduler); fragmentObservable.Select(x => x.Item3 ? IcParameters.Instance.LightModifications : null) .SelectMany(async mods => await GenerateFragmentLabelsAsync(mods)) .Subscribe(labels => FragmentLabels = labels); fragmentObservable.Where(x => x.Item3) .SelectMany(async mods => await GenerateFragmentLabelsAsync(IcParameters.Instance.HeavyModifications)) .Subscribe(labels => { HeavyFragmentLabels.ChangeTrackingEnabled = false; HeavyFragmentLabels = labels; }); IcParameters.Instance.WhenAnyValue(x => x.LightModifications) .Where(_ => SelectedPrSm != null).Select(mods => ShowHeavy ? mods : null) .SelectMany(async mods => await GenerateFragmentLabelsAsync(mods)) .Subscribe(labels => FragmentLabels = labels); IcParameters.Instance.WhenAnyValue(x => x.HeavyModifications) .Where(_ => SelectedPrSm != null && ShowHeavy) .SelectMany(async mods => await GenerateFragmentLabelsAsync(mods)) .Subscribe(labels => { HeavyFragmentLabels.ChangeTrackingEnabled = false; HeavyFragmentLabels = labels; }); EnableFragmentRowVirtualization = true; EnablePrecursorRowVirtualization = false; }
public void Dispose() { // We need to make sure that all outstanding writes are flushed // before we bail AsyncSubject<byte[]>[] requests; if (MemoizedRequests == null) { return; } lock (MemoizedRequests) { var mq = Interlocked.Exchange(ref MemoizedRequests, null); if (mq == null) { return; } requests = mq.CachedValues().ToArray(); MemoizedRequests = null; actionTaken.OnCompleted(); flushThreadSubscription.Dispose(); } IObservable<byte[]> requestChain = null; if (requests.Length > 0) { // Since these are all AsyncSubjects, most of them will replay // immediately, except for the ones still outstanding; we'll // Merge them all then wait for them all to complete. requestChain = requests.Merge(System.Reactive.Concurrency.Scheduler.Immediate) .Timeout(TimeSpan.FromSeconds(30), Scheduler) .Aggregate((acc, x) => x); } requestChain = requestChain ?? Observable.Return(new byte[0]); requestChain.SelectMany(FlushCacheIndex(true)).Subscribe(_ => { }); disposed = true; }
public ThumbNailConverter() { thumbCache = new MemoizingMRUCache<string, ImageSource>(loadThumb, MAX_THUMBNAILS); }