Diagnostics: When Calling ServerTextControl.Create() Failed
Under rare conditions, the creation of a new ServerTextControl instance can fail and the Dispose method returns false. This article explains the reasons and how what to do in these cases.

Under rare conditions, the creation of a new Server
The TXTextControl object must have been completely loaded to use this method.
In these cases, the Create method returned false and the instance should not be used.
Restart IIS?
Some users report that only an IIS restart helps to resolve this situation. Technically, a restart helps as the process is re-created and existing USER handles are being released. But in fact, only USER handles must be released and there is no need to restart IIS or the worker process.
Possible Reasons
The most typical reason that a ServerTextControl cannot be created is that it is not possible to create a new Window handle. In Windows, there is a limit of 10,000 USER handles and 10,000 GDI objects handles. If this number is exceeded, it is not possible to create a new ServerTextControl instance. In typical applications, it is very most unlikely that this number of handles is created.
Sometimes, we see reports from users that this issue is caused after several days and very inconsistent or sporadic. Most likely, in these cases, the ServerTextControl instances are not properly disposed. It is very important to dispose ServerTextControl objects explicitly. We recommend to use them in a using statement:
using (ServerTextControl serverTextControl = new ServerTextControl()) {
serverTextControl.Create();
}
A better way would be to check whether the Create method has been called successfully:
using (ServerTextControl serverTextControl = new ServerTextControl()) {
if (serverTextControl.Create() == true) {
// ...
}
}
ServerTextControl Factory Class
To monitor the created instances, we implemented a factory class that returns valid instances of ServerTextControl. This diagnostics class can be also used to check the number of active instances, USER handles and GDI handles. Additionally, it can be used to dispose all active instances.
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace TXTextControl.Diagnostics {
/// <summary>
/// Singleton factory class to return and manage ServerTextControl instances.
/// </summary>
public sealed class ServerTextControlFactory {
// private fields
private static readonly ServerTextControlFactory _instance =
new ServerTextControlFactory();
private List<ServerTextControl> _activeControls;
[DllImport("User32")]
extern public static int GetGuiResources(IntPtr hProcess, int uiFlags);
private enum ResourceType {
Gdi = 0,
User = 1
}
static ServerTextControlFactory() {
}
private ServerTextControlFactory() {
_activeControls = new List<ServerTextControl>();
}
/// <summary>
/// Returns the singleton instance.
/// </summary>
public static ServerTextControlFactory Instance {
get {
return _instance;
}
}
/// <summary>
/// Returns the number of active ServerTextControls that are not disposed.
/// </summary>
public int Count {
get {
return _activeControls.Count;
}
}
/// <summary>
/// Returns the total number of USER handles in current process.
/// </summary>
public int UserHandles {
get {
var processHandle = Process.GetCurrentProcess().Handle;
return GetGuiResources(processHandle, (int)ResourceType.User);
}
}
/// <summary>
/// Returns the total number of GDI handles in current process.
/// </summary>
public int GdiHandles {
get {
var processHandle = Process.GetCurrentProcess().Handle;
return GetGuiResources(processHandle, (int)ResourceType.Gdi);
}
}
/// <summary>
/// Disposes all active ServerTextControl instances.
/// </summary>
public int DisposeAll() {
int numControls = _activeControls.Count;
int i;
for (i = 0; i < numControls; i++) {
_activeControls[0].Dispose();
}
return i;
}
/// <summary>
/// Returns a new ServerTextControl instance and adds it to the list of
/// active instances.
/// Returns null in case a new ServerTextControl instance could not be created.
/// </summary>
public ServerTextControl? CreateServerTextControl() {
// create a new ServerTextControl instance and listen for the disposal
ServerTextControl serverTextControl = new ServerTextControl();
// trying to create - if creation fails, dispose the object and return null
if (serverTextControl.Create() == false) {
serverTextControl.Dispose();
return null;
}
// attached the Disposed event to clean up list of instances
serverTextControl.Disposed += ServerTextControl_Disposed;
// add to list of instances
_activeControls.Add(serverTextControl);
return serverTextControl;
}
private void ServerTextControl_Disposed(object sender, EventArgs e) {
// remove from list of instances
_activeControls.Remove((ServerTextControl)sender);
}
}
}
Using the Class
This class uses the singleton pattern and can be created only once in an application:
ServerTextControlFactory serverTextControlFactory = ServerTextControlFactory.Instance;
Once created, the CreateServerTextControl method creates and returns a new instance:
using (ServerTextControl? tx = serverTextControlFactory.CreateServerTextControl()) {
if (tx != null) {
tx.Text = "Test";
}
}
When using this factory class, it is not required to create the ServerTextControl before using it. This is handled in the factory itself.
The ServerTextControlFactory creates and returns a new instance of ServerTextControl and stores it in a list. In case the instance cannot be created, the class returns null. When the instance is disposed, it is removed from that list again automatically. The method ServerTextControlFactory.Count returns the number of active ServerTextControl instances.
When executing the following code, the created ServerTextControl instance is disposed explicitly in the using statement. Therefore, the counter should be 0 after a successful execution.
using (ServerTextControl tx = serverTextControlFactory.CreateServerTextControl()) {
Console.WriteLine(serverTextControlFactory.Count);
if (tx != null) {
tx.Text = "Test";
}
}
Console.WriteLine(serverTextControlFactory.Count);
Number of instances: 1
Number of instances: 0
In case the ServerTextControl is not disposed, the active instance stays in the list until disposed:
Console.WriteLine("Number of instances: {0}", serverTextControlFactory.Count);
ServerTextControl tx = serverTextControlFactory.CreateServerTextControl();
Console.WriteLine("Number of instances: {0}", serverTextControlFactory.Count);
Number of instances: 0
Number of instances: 1
Debugging
When using this factory class in your application, you can always monitor the number of instances to find leaks. In case you would like to dispose all instances - for debugging purposes - the factory class provides the DisposeAll method that loops through all stored instances in order to dispose them:
Console.WriteLine("Number of instances: {0}", serverTextControlFactory.Count);
for (int i = 0; i < 5; i++) {
ServerTextControl tx = serverTextControlFactory.CreateServerTextControl();
Console.WriteLine("Number of instances: {0}", serverTextControlFactory.Count);
}
Console.WriteLine("Disposed instances: {0}", serverTextControlFactory.DisposeAll());
Number of instances: 0
Number of instances: 1
Number of instances: 2
Number of instances: 3
Number of instances: 4
Number of instances: 5
Disposed instances: 5
Handle Counter
Additionally, the factory class provides properties to return the number of USER and GDI handles in the current process:
Console.WriteLine("USER handles: {0}", serverTextControlFactory.UserHandles);
Console.WriteLine("GDI handles: {0}", serverTextControlFactory.GdiHandles);
USER handles: 30
GDI handles: 26
Further Help
If you need assistance of further help debugging these kind of problems, talk to our engineers - we are here to help!
Download and Fork This Sample on GitHub
We proudly host our sample code on github.com/TextControl.
Please fork and contribute.
ASP.NET
Integrate document processing into your applications to create documents such as PDFs and MS Word documents, including client-side document editing, viewing, and electronic signatures.
- Angular
- Blazor
- React
- JavaScript
- ASP.NET MVC, ASP.NET Core, and WebForms
Related Posts
TX Text Control 33.0 SP3 is Now Available: What's New in the Latest Version
TX Text Control 33.0 Service Pack 3 is now available, offering important updates and bug fixes for all platforms. If you use TX Text Control in your document processing applications, this service…
TX Text Control 33.0 SP2 is Now Available: What's New in the Latest Version
TX Text Control 33.0 Service Pack 2 is now available, offering important updates and bug fixes for all platforms. If you use TX Text Control in your document processing applications, this service…
Document Lifecycle Optimization: Leveraging TX Text Control's Internal Format
Maintaining the integrity and functionality of documents throughout their lifecycle is paramount. TX Text Control provides a robust ecosystem that focuses on preserving documents in their internal…
Expert Implementation Services for Legacy System Modernization
We are happy to officially announce our partnership with Quality Bytes, a specialized integration company with extensive experience in modernizing legacy systems with TX Text Control technologies.
Service Pack Releases: What's New in TX Text Control 33.0 SP1 and 32.0 SP5
TX Text Control 33.0 Service Pack 1 and TX Text Control 32.0 Service Pack 5 have been released, providing important updates and bug fixes across platforms. These service packs improve the…