private List <TemplateEntry> GetTemplatePool(FrameworkTemplate template) { List <TemplateEntry> instances; if (!_pooledInstances.TryGetValue(template, out instances)) { _pooledInstances[template] = instances = new List <TemplateEntry>(); } return(instances); }
internal View DequeueTemplate(FrameworkTemplate template) { var list = GetTemplatePool(template); View instance; if (list.Count == 0) { if (_trace.IsEnabled) { _trace.WriteEventActivity(TraceProvider.CreateTemplate, EventOpcode.Send, new[] { ((Func <View>)template).Method.DeclaringType.ToString() }); } if (this.Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { this.Log().Debug($"Creating new template, id={GetTemplateDebugId(template)} IsPoolingEnabled:{IsPoolingEnabled}"); } instance = template.LoadContent() ?? new Grid(); if (IsPoolingEnabled && instance is IFrameworkElement) { DependencyObjectExtensions.RegisterParentChangedCallback((DependencyObject)instance, template, OnParentChanged); } } else { int position = list.Count - 1; instance = list[position].Control; list.RemoveAt(position); if (_trace.IsEnabled) { _trace.WriteEventActivity(TraceProvider.ReuseTemplate, EventOpcode.Send, new[] { instance.GetType().ToString() }); } if (this.Log().IsEnabled(Microsoft.Extensions.Logging.LogLevel.Debug)) { this.Log().Debug($"Recycling template, id={GetTemplateDebugId(template)}, {list.Count} items remaining in cache"); } } #if USE_HARD_REFERENCES if (IsPoolingEnabled) { _activeInstances.Add(instance); } #endif return(instance); }
private string GetTemplateDebugId(FrameworkTemplate template) { //Grossly inefficient, should only be used for debug logging int i = -1; foreach (var kvp in _pooledInstances) { i++; var pooledTemplate = kvp.Key; if (template?.Equals(pooledTemplate) ?? false) { var func = ((Func <View>)template); return($"{i}({func.Method.DeclaringType}.{func.Method.Name})"); } } return("Unknown"); }
internal void ReleaseTemplateRoot(View root, FrameworkTemplate template) => OnParentChanged(root, template, args: null);