/// <summary> /// Partially fill out BreakRecordTable by pre-calculating BreakRecords. /// This callback is invoked when background pagination is enabled and /// BreakRecordTable is not completely updated yet. /// </summary> private object OnBackgroundPagination(object arg) { DateTime dtStart = DateTime.Now; DateTime dtStop; _backgroundPaginationOperation = null; // Clear out pending request. // Ensure usage from just one Dispatcher object. // FlowDocumentPaginator runs its own layout, hence there is a need // to protect it from random access from other threads. _dispatcherObject.VerifyAccess(); // Detect reentrancy. if (_document.StructuralCache.IsFormattingInProgress) { throw new InvalidOperationException(SR.Get(SRID.FlowDocumentFormattingReentrancy)); } // Ignore this formatting request, if the element was already disposed. if (_document.StructuralCache.PtsContext.Disposed) { return(null); } // Disable processing of the queue during blocking operations to prevent unrelated reentrancy. using (_document.Dispatcher.DisableProcessing()) { _document.StructuralCache.IsFormattingInProgress = true; // Set reentrancy flag try { for (int index = 0; index < _asyncRequests.Count; index++) { AsyncRequest asyncRequest = _asyncRequests[index]; if (asyncRequest.Process()) { _asyncRequests.RemoveAt(index); index--; // Offset the index add } } dtStop = DateTime.Now; if (_backgroundPagination && !_brt.IsClean) { // Calculate BreakRecords until entire content is calculated or // specific time span has been exceeded (_paginationTimeout). while (!_brt.IsClean) { // Get the first invalid entry in the BreakRecordTable, calculate // BreakRecord for it and update BreakRecordTable with the calculated // value. FormatPage(_brt.Count); // Update time span. dtStop = DateTime.Now; long timeSpan = (dtStop.Ticks - dtStart.Ticks) / TimeSpan.TicksPerMillisecond; if (timeSpan > _paginationTimeout) { break; } } // Initiate the next async operation. InitiateNextAsyncOperation(); } } finally { _document.StructuralCache.IsFormattingInProgress = false; // Clear reentrancy flag. } } return(null); }