private void GetEngineResults() { for (int i = 0; i < engineIterations.Count; i++) { TickEngine engine = engineIterations[i]; engine.WaitTask(); #if CLRPROFILER CLRProfilerControl.LogWriteLine(tasksRemaining + " tasks remaining"); #endif --tasksRemaining; } }
static void Main(string[] args) { if (CLRProfilerControl.ProcessIsUnderProfiler) { Console.WriteLine("Process is running under CLRProfiler"); } else { Console.WriteLine("Process is not running under CLRProfiler - exiting"); return; } string.Format(""); // Make sure we get rid of everything we can get rid of GC.Collect(); GC.WaitForPendingFinalizers(); // This will trigger another garbage collection and dump what's still live // This is our "before" snapshot. CLRProfilerControl.DumpHeap(); ht = new Hashtable(); for (int i = 0; i < 1000; i++) { ht[i] = string.Format("Value {0}", i); } // The memory is retained because ht is a static - enable the following statement // to make sure the garbage collector can clean up //ht = null; // Make sure we get rid of everything we can get rid of GC.Collect(); GC.WaitForPendingFinalizers(); // This will trigger another garbage collection and dump what's still live // This is our "after" snapshot. CLRProfilerControl.DumpHeap(); Console.WriteLine("Press any key to exit"); Console.ReadLine(); }
public static object Load(System.Xaml.XamlReader reader) { if (reader == null) { throw new ArgumentNullException("reader"); } object root = null; try { root = Load(reader, null); } catch (Exception e) { IUriContext uriContext = reader as IUriContext; Uri baseUri = (uriContext != null) ? uriContext.BaseUri : null; // Don't wrap critical exceptions or already-wrapped exceptions. if (MS.Internal.CriticalExceptions.IsCriticalException(e) || !ShouldReWrapException(e, baseUri)) { throw; } RewrapException(e, baseUri); } finally { if (TraceMarkup.IsEnabled) { TraceMarkup.Trace(TraceEventType.Stop, TraceMarkup.Load, root); } EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Event.WClientParseXmlEnd); #if DEBUG_CLR_MEM if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) { CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass); } #endif // DEBUG_CLR_MEM } return(root); }
static void Main(string[] args) { // Set our "before" marker in the log file CLRProfilerControl.LogWriteLine("Before loop - time = {0} milliseconds", DateTime.Now.Millisecond); ht = new Hashtable(); for (int i = 0; i < 1000; i++) { ht[i] = string.Format("Value {0}", i); } // Set our "after" marker in the log file CLRProfilerControl.LogWriteLine("After loop - time = {0} milliseconds", DateTime.Now.Millisecond); // Do some more to make things more interesting... for (int i = 0; i < 1000; i++) { ht[i] = string.Format("Value {0}", i); } // Set another "after" marker in the log file CLRProfilerControl.LogWriteLine("After second loop - time = {0} milliseconds", DateTime.Now.Millisecond); // The memory is retained because ht is a static - enable the following statement // to make sure the garbage collector can clean up // ht = null; // Make sure we get rid of everything we can get rid of GC.Collect(); GC.WaitForPendingFinalizers(); // This will trigger another garbage collection and dump what's still live // This is our "after" snapshot. CLRProfilerControl.DumpHeap(); Console.WriteLine("Press any key to exit"); Console.ReadLine(); }
public override void Run(ModelLoaderInterface loader) { Factory.Parallel.SetMode(parallelMode); Factory.SysLog.ResetConfiguration(); this.loader = loader; try { if (loader.OptimizeOutput == null) { Directory.CreateDirectory(Path.GetDirectoryName(FileName)); File.Delete(FileName); } } catch (Exception ex) { log.Error("Error while creating directory and deleting '" + FileName + "'.", ex); return; } log.Notice("Beginning Genetic Optimize of: "); log.Notice(loader.Name + " model loader. Type: " + loader.GetType().Name); loader.QuietMode = true; loader.OnInitialize(ProjectProperties); optimizeVariables = new List <ModelProperty>(); for (int i = 0; i < loader.Variables.Count; i++) { ModelProperty var = loader.Variables[i]; if (var.Optimize) { optimizeVariables.Add(var); } } // Get Total Number of Bits int totalBits = 0; for (int i = 0; i < optimizeVariables.Count; i++) { ModelProperty var = optimizeVariables[i]; int bits = Convert.ToString(var.Count - 1, 2).Length; totalBits += bits; } if (optimizeVariables.Count == 1) { generationCount = 1; } // Get the highest count. populationCount = totalPasses / generationCount; tasksRemaining = totalPasses; log.Notice("Assigning genomes."); // Create initial set of random chromosomes. generation = new List <Chromosome>(); // This list assures we never retry a previous one twice. alreadyTried = new List <Chromosome>(); // Create a genome holder. int[] genome = new int[optimizeVariables.Count]; // Indexes for going through randomList int[] indexes = new int[optimizeVariables.Count]; // for( int repeat=0; repeat < Math.Min(optimizeVariables.Count,2); repeat++) { // //Get random values for each. List <List <int> > randomLists = new List <List <int> >(); for (int i = 0; i < optimizeVariables.Count; i++) { randomLists.Add(GetRandomIndexes(optimizeVariables[i])); } // Create initial population for (int loop = 0; loop < populationCount; loop++) { // Set the genome from the randomLists using the indexes. for (int i = 0; i < optimizeVariables.Count; i++) { genome[i] = randomLists[i][indexes[i]]; } Chromosome chromosome = new Chromosome(genome); log.Debug(chromosome.ToString()); generation.Add(chromosome); alreadyTried.Add(chromosome); for (int i = 0; i < indexes.Length; i++) { indexes[i]++; ModelProperty var = optimizeVariables[i]; if (indexes[i] >= populationCount) { indexes[i] = 0; } } } // } #if CLRPROFILER CLRProfilerControl.LogWriteLine("Entering Genetic Loop"); CLRProfilerControl.AllocationLoggingActive = true; CLRProfilerControl.CallLoggingActive = false; #endif int totalEngineCount = Environment.ProcessorCount * generationCount; // Pre-setup engines. This causes the progress // bar to show a complete set of information for all // generations. var iteration = 1; for (int genCount = 0; genCount < generationCount && !CancelPending; genCount++) { // Assign fitness values var topModels = new List <ModelInterface>(); for (int i = generation.Count - 1; i >= 0; i--) { Chromosome chromosome = generation[i]; if (!chromosome.FitnessAssigned) { ModifyVariables(chromosome); var model = ProcessLoader(loader, i); topModels.Add(model); } else { tasksRemaining--; log.Debug("Saves processing on " + chromosome + "!"); } } int tasksPerEngine = CalculateTasksPerEngine(topModels.Count); ModelInterface topModel = new Portfolio(); int passCount = 0; foreach (var model in topModels) { topModel.Chain.Dependencies.Add(model.Chain); passCount++; if (passCount % tasksPerEngine == 0) { var engine = SetupEngine(true, "Iteration" + ++iteration); engine.Model = topModel; engine.QueueTask(); engineIterations.Add(engine); topModel = new Portfolio(); if (engineIterations.Count >= Environment.ProcessorCount) { ProcessIteration(); } } } if (topModel.Chain.Dependencies.Count > 0) { var engine = SetupEngine(true, "Iteration" + ++iteration); engine.Model = topModel; engine.QueueTask(); engineIterations.Add(engine); } if (engineIterations.Count > 0) { ProcessIteration(); } generation.Sort(); log.Notice("After sorting generation..."); double maxFitness = 0; for (int i = 0; i < generation.Count; i++) { log.Debug(generation[i].ToString()); maxFitness = Math.Max(generation[i].Fitness, maxFitness); } // If none of the genes in the chromosome // had a positive fitness, stop here. if (maxFitness <= 0) { break; } List <Chromosome> newGeneration = new List <Chromosome>(); log.Notice("Crossover starting..."); while (newGeneration.Count < populationCount - 1) { Chromosome chromo1 = Roulette(); Chromosome chromo2; do { chromo2 = Roulette(); } while(chromo2.Equals(chromo1)); log.Debug("Before: " + chromo1 + " - " + chromo2); chromo1.DoubleCrossOver(chromo2); log.Debug("After: " + chromo1 + " - " + chromo2); if (alreadyTried.Contains(chromo1)) { chromo1 = alreadyTried[alreadyTried.IndexOf(chromo1)]; } else { alreadyTried.Add(chromo1); } if (alreadyTried.Contains(chromo2)) { chromo2 = alreadyTried[alreadyTried.IndexOf(chromo2)]; } else { alreadyTried.Add(chromo2); } newGeneration.Add(chromo1); newGeneration.Add(chromo2); } generation = newGeneration; } GetEngineResults(); WriteEngineResults(loader, engineIterations); engineIterations.Clear(); #if CLRPROFILER CLRProfilerControl.AllocationLoggingActive = false; CLRProfilerControl.CallLoggingActive = false; CLRProfilerControl.LogWriteLine("Exiting Genetic Loop"); #endif log.Notice("Genetic Algorithm Finished."); }
//[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking Bug: 29647 internal static object LoadBaml( Stream stream, ParserContext parserContext, object parent, bool closeStream) { object root = null; #if DEBUG_CLR_MEM bool clrTracingEnabled = false; // Use local pass variable to correctly log nested parses. int pass = 0; if (CLRProfilerControl.ProcessIsUnderCLRProfiler && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) { clrTracingEnabled = true; pass = ++_CLRBamlPass; CLRProfilerControl.CLRLogWriteLine("Begin_BamlParse_{0}", pass); } #endif // DEBUG_CLR_MEM EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientParseBamlBegin, parserContext.BaseUri); if (TraceMarkup.IsEnabled) { TraceMarkup.Trace(TraceEventType.Start, TraceMarkup.Load); } try { // // If the stream contains info about the Assembly that created it, // set StreamCreatedAssembly from the stream instance. // IStreamInfo streamInfo = stream as IStreamInfo; if (streamInfo != null) { parserContext.StreamCreatedAssembly = streamInfo.Assembly; } Baml2006ReaderSettings readerSettings = XamlReader.CreateBamlReaderSettings(); readerSettings.BaseUri = parserContext.BaseUri; readerSettings.LocalAssembly = streamInfo.Assembly; // We do not set OwnsStream = true so the Baml2006Reader will not close the stream. // Calling code is responsible for disposing the stream if (readerSettings.BaseUri == null || String.IsNullOrEmpty(readerSettings.BaseUri.ToString())) { readerSettings.BaseUri = BaseUriHelper.PackAppBaseUri; } var reader = new Baml2006ReaderInternal(stream, new Baml2006SchemaContext(readerSettings.LocalAssembly), readerSettings, parent); // We don't actually use the GeneratedInternalTypeHelper any more. // But for v3 compat, don't allow loading of internals in PT unless there is one. Type internalTypeHelper = null; if (streamInfo.Assembly != null) { try { internalTypeHelper = XamlTypeMapper.GetInternalTypeHelperTypeFromAssembly(parserContext); } // This can perform attribute reflection which will fail if the assembly has unresolvable // attributes. If that happens, just assume there is no helper. catch (Exception e) { if (MS.Internal.CriticalExceptions.IsCriticalException(e)) { throw; } } } if (internalTypeHelper != null) { XamlAccessLevel accessLevel = XamlAccessLevel.AssemblyAccessTo(streamInfo.Assembly); XamlLoadPermission loadPermission = new XamlLoadPermission(accessLevel); loadPermission.Assert(); try { root = WpfXamlLoader.LoadBaml(reader, parserContext.SkipJournaledProperties, parent, accessLevel, parserContext.BaseUri); } finally { CodeAccessPermission.RevertAssert(); } } else { root = WpfXamlLoader.LoadBaml(reader, parserContext.SkipJournaledProperties, parent, null, parserContext.BaseUri); } DependencyObject dObject = root as DependencyObject; if (dObject != null) { dObject.SetValue(BaseUriHelper.BaseUriProperty, readerSettings.BaseUri); } Application app = root as Application; if (app != null) { app.ApplicationMarkupBaseUri = GetBaseUri(readerSettings.BaseUri); } Debug.Assert(parent == null || root == parent); } finally { if (TraceMarkup.IsEnabled) { TraceMarkup.Trace(TraceEventType.Stop, TraceMarkup.Load, root); } EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml | EventTrace.Keyword.KeywordPerf, EventTrace.Event.WClientParseBamlEnd, parserContext.BaseUri); if (closeStream && stream != null) { stream.Close(); } #if DEBUG_CLR_MEM if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) { CLRProfilerControl.CLRLogWriteLine("End_BamlParse_{0}", pass); } #endif // DEBUG_CLR_MEM } return(root); }
/// <summary> /// Reads XAML from the passed stream, building an object tree and returning the /// root of that tree. Wrap a CompatibilityReader with another XmlReader that /// uses the passed reader settings to allow validation of xaml. /// </summary> /// <param name="reader">XmlReader to use. This is NOT wrapped by any /// other reader</param> /// <param name="context">Optional parser context. May be null </param> /// <param name="parseMode">Sets synchronous or asynchronous parsing</param> /// <returns>object root generated after xml parsed</returns> // Note this is the internal entry point for XPS. XPS calls here so // its reader is not wrapped with a Markup Compat Reader. internal static object Load( XmlReader reader, ParserContext parserContext, XamlParseMode parseMode) { if (parseMode == XamlParseMode.Uninitialized || parseMode == XamlParseMode.Asynchronous) { XamlReader xamlReader = new XamlReader(); return(xamlReader.LoadAsync(reader, parserContext)); } if (parserContext == null) { parserContext = new ParserContext(); } #if DEBUG_CLR_MEM bool clrTracingEnabled = false; // Use local pass variable to correctly log nested parses. int pass = 0; if (CLRProfilerControl.ProcessIsUnderCLRProfiler && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) { clrTracingEnabled = true; pass = ++_CLRXamlPass; CLRProfilerControl.CLRLogWriteLine("Begin_XamlParse_{0}", pass); } #endif // DEBUG_CLR_MEM EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Event.WClientParseXmlBegin, parserContext.BaseUri); if (TraceMarkup.IsEnabled) { TraceMarkup.Trace(TraceEventType.Start, TraceMarkup.Load); } object root = null; try { if (parserContext.BaseUri == null || String.IsNullOrEmpty(parserContext.BaseUri.ToString())) { if (reader.BaseURI == null || String.IsNullOrEmpty(reader.BaseURI.ToString())) { parserContext.BaseUri = BaseUriHelper.PackAppBaseUri; } else { parserContext.BaseUri = new Uri(reader.BaseURI); } } System.Xaml.XamlXmlReaderSettings settings = new System.Xaml.XamlXmlReaderSettings(); settings.IgnoreUidsOnPropertyElements = true; settings.BaseUri = parserContext.BaseUri; settings.ProvideLineInfo = true; XamlSchemaContext schemaContext = parserContext.XamlTypeMapper != null ? parserContext.XamlTypeMapper.SchemaContext : GetWpfSchemaContext(); System.Xaml.XamlXmlReader xamlXmlReader = new System.Xaml.XamlXmlReader(reader, schemaContext, settings); root = Load(xamlXmlReader, parserContext); reader.Close(); } catch (Exception e) { // Don't wrap critical exceptions or already-wrapped exceptions. if (MS.Internal.CriticalExceptions.IsCriticalException(e) || !ShouldReWrapException(e, parserContext.BaseUri)) { throw; } RewrapException(e, parserContext.BaseUri); } finally { if (TraceMarkup.IsEnabled) { TraceMarkup.Trace(TraceEventType.Stop, TraceMarkup.Load, root); } EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXamlBaml, EventTrace.Event.WClientParseXmlEnd, parserContext.BaseUri); #if DEBUG_CLR_MEM if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) { CLRProfilerControl.CLRLogWriteLine("End_XamlParse_{0}", pass); } #endif // DEBUG_CLR_MEM } return(root); }
/// <summary> /// Render method renders the visual tree. /// </summary> void ICompositionTarget.Render(bool inResize, DUCE.Channel channel) { #if DEBUG_CLR_MEM bool clrTracingEnabled = false; if (CLRProfilerControl.ProcessIsUnderCLRProfiler && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) { clrTracingEnabled = true; ++_renderCLRPass; CLRProfilerControl.CLRLogWriteLine("Begin_FullRender_{0}", _renderCLRPass); } #endif // DEBUG_CLR_MEM // // Now we render the scene // #if MEDIA_PERFORMANCE_COUNTERS _frameRateTimer.Begin(); #endif if (_rootVisual.Value != null) { bool etwTracingEnabled = false; if (EventTrace.IsEnabled(EventTrace.Keyword.KeywordGeneral | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info)) { etwTracingEnabled = true; EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientPrecomputeSceneBegin, EventTrace.Keyword.KeywordGraphics | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info, PerfService.GetPerfElementID(this)); } #if MEDIA_PERFORMANCE_COUNTERS _precomputeRateTimer.Begin(); #endif // precompute is channel agnostic _rootVisual.Value.Precompute(); #if MEDIA_PERFORMANCE_COUNTERS _precomputeRateTimer.End(); #endif if (etwTracingEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientPrecomputeSceneEnd, EventTrace.Keyword.KeywordGraphics | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info); } #if DEBUG MediaTrace.RenderPass.Trace("Full Update"); #endif if (etwTracingEnabled) { EventTrace.EventProvider.TraceEvent( EventTrace.Event.WClientCompileSceneBegin, EventTrace.Keyword.KeywordGraphics | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info, PerfService.GetPerfElementID(this)); } #if MEDIA_PERFORMANCE_COUNTERS _renderRateTimer.Begin(); #endif Compile(channel); #if MEDIA_PERFORMANCE_COUNTERS _renderRateTimer.End(); #endif if (etwTracingEnabled) { EventTrace.EventProvider.TraceEvent( EventTrace.Event.WClientCompileSceneEnd, EventTrace.Keyword.KeywordGraphics | EventTrace.Keyword.KeywordPerf, EventTrace.Level.Info); } } #if DEBUG_CLR_MEM if (clrTracingEnabled && CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance) { CLRProfilerControl.CLRLogWriteLine("End_FullRender_{0}", _renderCLRPass); } #endif // DEBUG_CLR_MEM #if MEDIA_PERFORMANCE_COUNTERS _frameRateTimer.End(); System.Console.WriteLine("RENDERING PERFORMANCE DATA"); System.Console.WriteLine("Frame rendering time: " + _frameRateTimer.TimeOfLastPeriod + "ms"); System.Console.WriteLine("Frame precompute time: " + _precomputeRateTimer.TimeOfLastPeriod + "ms"); System.Console.WriteLine("Frame render time: " + _renderRateTimer.TimeOfLastPeriod + "ms"); #endif }
/// <summary> /// Tells ContextLayoutManager to finalize possibly async update. /// Used before accessing services off Visual. /// </summary> //[CodeAnalysis("AptcaMethodsShouldOnlyCallAptcaMethods")] //Tracking internal void UpdateLayout() { VerifyAccess(); //make UpdateLayout to be a NOP if called during UpdateLayout. if (_isInUpdateLayout || _measuresOnStack > 0 || _arrangesOnStack > 0 || _isDead) { return; } #if DEBUG_CLR_MEM bool clrTracingEnabled = false; // Start over with the Measure and arrange counters for this layout pass int measureCLRPass = 0; int arrangeCLRPass = 0; if (CLRProfilerControl.ProcessIsUnderCLRProfiler) { clrTracingEnabled = true; if (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance) { ++_layoutCLRPass; CLRProfilerControl.CLRLogWriteLine("Begin_Layout_{0}", _layoutCLRPass); } } #endif // DEBUG_CLR_MEM bool etwTracingEnabled = false; long perfElementID = 0; const EventTrace.Keyword etwKeywords = EventTrace.Keyword.KeywordLayout | EventTrace.Keyword.KeywordPerf; if (!_isUpdating && EventTrace.IsEnabled(etwKeywords, EventTrace.Level.Info)) { etwTracingEnabled = true; perfElementID = PerfService.GetPerfElementID(this); EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientLayoutBegin, etwKeywords, EventTrace.Level.Info, perfElementID, EventTrace.LayoutSource.LayoutManager); } int cnt = 0; bool gotException = true; UIElement currentElement = null; try { invalidateTreeIfRecovering(); while (hasDirtiness || _firePostLayoutEvents) { if (++cnt > 153) { //loop detected. Lets go over to background to let input/user to correct the situation. //most frequently, we get such a loop as a result of input detecting a mouse in the "bad spot" //and some event handler oscillating a layout-affecting property depending on hittest result //of the mouse. Going over to background will not break the loopp but will allow user to //move the mouse so that it goes out of the "bad spot". Dispatcher.BeginInvoke(DispatcherPriority.Background, _updateLayoutBackground, this); currentElement = null; gotException = false; if (etwTracingEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientLayoutAbort, etwKeywords, EventTrace.Level.Info, 0, cnt); } return; } //this flag stops posting update requests to MediaContext - we are already in one //note that _isInUpdateLayout is close but different - _isInUpdateLayout is reset //before firing LayoutUpdated so that event handlers could call UpdateLayout but //still could not cause posting of MediaContext work item. Posting MediaContext workitem //causes infinite loop in MediaContext. _isUpdating = true; _isInUpdateLayout = true; #if DEBUG_CLR_MEM if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Verbose)) { ++measureCLRPass; CLRProfilerControl.CLRLogWriteLine("Begin_Measure_{0}_{1}", _layoutCLRPass, measureCLRPass); } #endif // DEBUG_CLR_MEM if (etwTracingEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientMeasureBegin, etwKeywords, EventTrace.Level.Info, perfElementID); } // Disable processing of the queue during blocking operations to prevent unrelated reentrancy. using (Dispatcher.DisableProcessing()) { //loop for Measure //We limit the number of loops here by time - normally, all layout //calculations should be done by this time, this limit is here for //emergency, "infinite loop" scenarios - yielding in this case will //provide user with ability to continue to interact with the app, even though //it will be sluggish. If we don't yield here, the loop is goign to be a deadly one //and it will be impossible to save results or even close the window. int loopCounter = 0; DateTime loopStartTime = new DateTime(0); while (true) { if (++loopCounter > 153) { loopCounter = 0; //first bunch of iterations is free, then we start count time //this way, we don't call DateTime.Now in most layout updates if (loopStartTime.Ticks == 0) { loopStartTime = DateTime.UtcNow; } else { TimeSpan loopDuration = (DateTime.UtcNow - loopStartTime); if (loopDuration.Milliseconds > 153 * 2) // 153*2 = magic*science { //loop detected. Lets go over to background to let input work. Dispatcher.BeginInvoke(DispatcherPriority.Background, _updateLayoutBackground, this); currentElement = null; gotException = false; if (etwTracingEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientMeasureAbort, etwKeywords, EventTrace.Level.Info, loopDuration.Milliseconds, loopCounter); } return; } } } currentElement = MeasureQueue.GetTopMost(); if (currentElement == null) { break; //exit if no more Measure candidates } currentElement.Measure(currentElement.PreviousConstraint); //dmitryt, } if (etwTracingEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientMeasureEnd, etwKeywords, EventTrace.Level.Info, loopCounter); EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientArrangeBegin, etwKeywords, EventTrace.Level.Info, perfElementID); } #if DEBUG_CLR_MEM if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Verbose)) { CLRProfilerControl.CLRLogWriteLine("End_Measure_{0}_{1}", _layoutCLRPass, measureCLRPass); ++arrangeCLRPass; CLRProfilerControl.CLRLogWriteLine("Begin_Arrange_{0}_{1}", _layoutCLRPass, arrangeCLRPass); } #endif // DEBUG_CLR_MEM //loop for Arrange //if Arrange dirtied the tree go clean it again //We limit the number of loops here by time - normally, all layout //calculations should be done by this time, this limit is here for //emergency, "infinite loop" scenarios - yielding in this case will //provide user with ability to continue to interact with the app, even though //it will be sluggish. If we don't yield here, the loop is goign to be a deadly one //and it will be impossible to save results or even close the window. loopCounter = 0; loopStartTime = new DateTime(0); while (MeasureQueue.IsEmpty) { if (++loopCounter > 153) { loopCounter = 0; //first bunch of iterations is free, then we start count time //this way, we don't call DateTime.Now in most layout updates if (loopStartTime.Ticks == 0) { loopStartTime = DateTime.UtcNow; } else { TimeSpan loopDuration = (DateTime.UtcNow - loopStartTime); if (loopDuration.Milliseconds > 153 * 2) // 153*2 = magic*science { //loop detected. Lets go over to background to let input work. Dispatcher.BeginInvoke(DispatcherPriority.Background, _updateLayoutBackground, this); currentElement = null; gotException = false; if (etwTracingEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientArrangeAbort, etwKeywords, EventTrace.Level.Info, loopDuration.Milliseconds, loopCounter); } return; } } } currentElement = ArrangeQueue.GetTopMost(); if (currentElement == null) { break; //exit if no more Measure candidates } Rect finalRect = getProperArrangeRect(currentElement); currentElement.Arrange(finalRect); //dmitryt, } if (etwTracingEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientArrangeEnd, etwKeywords, EventTrace.Level.Info, loopCounter); } #if DEBUG_CLR_MEM if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Verbose)) { CLRProfilerControl.CLRLogWriteLine("End_Arrange_{0}_{1}", _layoutCLRPass, arrangeCLRPass); } #endif // DEBUG_CLR_MEM //if Arrange dirtied the tree go clean it again //it is not neccesary to check ArrangeQueue sicnce we just exited from Arrange loop if (!MeasureQueue.IsEmpty) { continue; } //let LayoutUpdated handlers to call UpdateLayout //note that it means we can get reentrancy into UpdateLayout past this point, //if any of event handlers call UpdateLayout sync. Need to protect from reentrancy //in the firing methods below. _isInUpdateLayout = false; } fireSizeChangedEvents(); if (hasDirtiness) { continue; } fireLayoutUpdateEvent(); if (hasDirtiness) { continue; } fireAutomationEvents(); if (hasDirtiness) { continue; } fireSizeChangedEvents(); // if nothing is dirty, one last chance for any size changes to announce. } currentElement = null; gotException = false; } finally { _isUpdating = false; _layoutRequestPosted = false; _isInUpdateLayout = false; if (gotException) { if (etwTracingEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientLayoutException, etwKeywords, EventTrace.Level.Info, PerfService.GetPerfElementID(currentElement)); } //set indicator _gotException = true; _forceLayoutElement = currentElement; //make attempt to request the subsequent layout calc //some exception handler schemas use Idle priorities to //wait until dust settles. Then they correct the issue noted in the exception handler. //We don't want to attempt to re-do the operation on the priority higher then that. Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, _updateLayoutBackground, this); } } MS.Internal.Text.TextInterface.Font.ResetFontFaceCache(); MS.Internal.FontCache.BufferCache.Reset(); if (etwTracingEnabled) { EventTrace.EventProvider.TraceEvent(EventTrace.Event.WClientLayoutEnd, etwKeywords, EventTrace.Level.Info); } #if DEBUG_CLR_MEM if (clrTracingEnabled && (CLRProfilerControl.CLRLoggingLevel >= CLRProfilerControl.CLRLogState.Performance)) { CLRProfilerControl.CLRLogWriteLine("End_Layout_{0}", _layoutCLRPass); } #endif // DEBUG_CLR_MEM }