Large Documents
Long documents cost time in two places in a WPF application: while code builds them piece by piece in the editor, and while files with hundreds of pages are loaded, changed and saved. Both are under your control. Build content outside the editor and insert it at once, reuse instances for many files, and choose import and export settings that fit the task; Text Control's published measurements show what each of these changes and under which conditions.
Choose a 64-Bit Build
TX Text Control's native libraries come in a 32-bit and a 64-bit version, and the process of your application loads the matching set. A 64-bit process can use far more memory than a 32-bit one, which matters for documents with hundreds of pages and many images. 32-bit and 64-bit Applications shows how to set up the build configurations.
Build Large Content in One Step
When code builds a long document directly in the WPF TextControl, every insertion is recorded in the undo buffer and updates the editor. Two techniques reduce the work:
- Selection objects. Create a Selection object, set its text and formatting, and assign it to the Selection property. The text arrives formatted, in one operation, instead of being inserted, selected and formatted afterward.
- A ServerTextControl for the whole part. A
ServerTextControlkeeps no undo history and renders nothing for the screen. Build the part there and insert the result with Selection.Load, which the editor records as one undo step.
The following handler in MainWindow.xaml.cs builds a price list of 300 products and inserts it into textControl1 in one step:
using System.Windows;
using TXTextControl;
private void InsertPriceList_Click(object sender, RoutedEventArgs e)
{
byte[] priceList;
using (ServerTextControl tx = new ServerTextControl())
{
tx.Create();
tx.Selection = new Selection
{
Text = "Price List\r\n",
FontName = "Segoe UI",
FontSize = 360, // 18 points, in twips
Bold = true
};
for (int i = 1; i <= 300; i++)
{
// Text and formatting in one assignment
tx.Selection = new Selection
{
Text = $"Product {i:000}\t{i * 1.5m:0.00} EUR\r\n",
FontName = "Segoe UI",
FontSize = 220
};
}
tx.Save(out priceList, BinaryStreamType.InternalUnicodeFormat);
}
// The editor records the insertion as one undo step
textControl1.Selection.Load(priceList, BinaryStreamType.InternalUnicodeFormat);
}
The code works as follows:
- Each new
Selectioncarries its Text, FontName, FontSize and Bold settings, and the assignment inserts it at the input position of theServerTextControl. Font sizes are set in twips, 20 per point. - Save writes the list into a byte array in the TX Text Control format.
Selection.Loadof the editor exchanges its current selection with the list. One Ctrl+Z removes it again.
Text Control measured Selection objects at about twice the speed of inserting, selecting and formatting: documents with 10 sections and 10 to 100 paragraphs per section took 5.7 to 42.9 ms each with Selection objects and 10.6 to 88.9 ms the other way. The benchmark ran with ServerTextControl of TX Text Control .NET Server and its Core engine, with a warm-up, on hardware the article doesn't name; the blog article Speed Up Document Generation by Factor 2 Using Selection Objects in .NET C# has the details.
When the content must be built in the editor itself, switch the undo buffer off with IsUndoEnabled while your code runs; the reference recommends this for tasks such as generating reports, to save time and memory. Switch the Buffer Off in Undo and Redo shows the code and the XAML attribute.
Replace Text in Many Large Files
For files the user doesn't need to see, a ServerTextControl works through long documents with the same members as through short ones. Text Control measured this on an eight-core Ryzen 7 processor: loading an 80-page DOCX file with about 30,000 words, replacing five placeholders and saving it took 0.46 seconds. With one ServerTextControl that processed one file after another, 400 such documents, 32,000 pages in total, took 73.32 seconds, 0.18 seconds per document. The blog article High-Performance Text Replacement in Large DOCX Files using C# .NET doesn't name the product or the engine it used.
The following handler replaces a placeholder in all DOCX files of the folder Documents on a background thread and writes the results to Output:
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using TXTextControl;
private async void ReplacePlaceholders_Click(object sender, RoutedEventArgs e)
{
const string searchText = "%%company_name%%";
const string replacementText = "Text Control, LLC";
string[] files = Directory.GetFiles("Documents", "*.docx");
Directory.CreateDirectory("Output");
await Task.Run(() =>
{
// One instance for all files
using (ServerTextControl tx = new ServerTextControl())
{
tx.Create();
foreach (string file in files)
{
tx.Load(file, StreamType.WordprocessingML);
int start = 0;
int position;
while ((position = tx.Find(searchText, start, FindOptions.MatchCase)) != -1)
{
tx.Select(position, searchText.Length);
tx.Selection.Text = replacementText;
start = position + replacementText.Length;
}
tx.Save(System.IO.Path.Combine("Output", System.IO.Path.GetFileName(file)), StreamType.WordprocessingML);
}
}
});
MessageBox.Show(this, $"{files.Length} documents processed.");
}
The code works as follows:
- Each Load replaces the previous document of the instance, so the instance is created once for the whole folder.
- Find returns the position of the next occurrence from
starton, or -1. Select selects the occurrence, andSelection.Textreplaces it; the search continues behind the inserted text. Task.Runkeeps the dispatcher free while the files are processed. Background Operations adds progress and cancellation.
Preview Large PDF Files
A PDF file is rebuilt into an editable document when it's loaded, page by page. To show a large PDF file quickly, load only its first page, as Load a Quick Preview shows.
Keep PDF Output Small
SaveSettings.ImageCompressionQuality compresses the images of a PDF file, and ImageMaxResolution reduces images whose resolution is higher. Text Control saved a 10-page document with two images of 2400 × 1350 pixels as a PDF file of 14.68 MB with the lossless quality 100, and of 1.48 MB with a quality of 70. Reduce the Size of PDF Files shows the settings, and the blog article Best Practices for Image Compression when Exporting to PDF in .NET C# all measured values.
Next Steps
- Mail Merge Performance — merges with long merge blocks and many pages.
- Memory Usage and Resource Disposal — what documents and instances hold in memory.
- Document Loading and Conversion — load and convert many documents efficiently.
- Background Operations — keep the window responsive during long work.