KB Article T931191
Visible to All Users

DevExpress WinForms Troubleshooting - Application Performance

Cheat Sheets, Best Practices and Troubleshooting


Sometimes you may notice that an application, a particular application module, a form, or a user control operates slowly. Based on our experience, such issues are usually not directly related to our components.

In this article, you will find information on the most common performance issues and ways to resolve them.

Known Issues

Issue 1: Application or its module is slowly loaded the first time you run it.

Cause 1: In .NET, any code that is run for the first time requires more time for execution than subsequent calls of the same code.

Solution: Refer to the following article to learn more about this behavior and how to overcome it: Why does my code take longer to execute the first time it's run?

Cause 2: Verification of signed assemblies

Solution: Allow the verification to be bypassed using the generatePublisherEvidence option.

Starting with version 11.2 we sign our assemblies with a Microsoft digital certificate. According to the Optimize Authenticode item at the Application Startup Time Microsoft documentation, the verification adds to the startup time - authenticode-signed assemblies have to be verified with the certification authority (CA). This verification can be time consuming because it can require connecting to the network several times to download current certificate revocation lists.
Since .NET Framework 3.5, there is a generatePublisherEvidence option that allows the Authenticode verification to be bypassed - you can add the generatePublisherEvidence setting to the app.exe.config file and disable it.
Please refer to the following articles where this solution is described in detail.
Optimize Authenticode
generatePublisherEvidence Element

Issue 2: A particular form, user control, or application module is loaded slowly.

Cause: A form or control contains too many components.

When a control or component is added to a form, Visual Studio generates corresponding code in the InitializeComponent method in the Form.Designer file. When a form is shown, it takes some time to execute this code. The more code the InitializeComponent method contains, the more time it takes to load this form.

Solution: Check if too many components are simultaneously loaded on a form or a user control and reduce their number.

How to determine that there are too many components on a form or a user control.
DevExpress components are more feature-rich than standard ones and they may require a little bit more time to complete the initialization. Here are the main reasons why this happens:

  • Unlike standard components, our components use Skins. Skin elements are presented by corresponding images, either raster or vector. It takes time to load all skin elements used to render the components.
  • DevExpress components have a lot of different functions. Their code may be more complex than the code of standard components.
  • Finally, many DevExpress components (e.g., Grid Control) have many dependencies that are loaded when a form is being initialized.

Usually, you will not see any significant difference in load time between our and standard components. To check this statement, you can create a test project with standard component counterparts and compare the load time. If our components are much slower, feel free to contact us and create a ticket.

Consider reducing the number of controls placed on a single form or user control (see below). This helps you to:

  • Boost the application's performance.
  • Improve the design of your forms and make them simpler to work with for your end-users.

How to reduce the number of components located on a form or a user control.
Here is what you can do to reduce the number of controls placed on a single form:

  • Instead of placing all components onto a form directly, split it into several modules. Create an XtraUserControl for each separate module.
  • Use navigation containers: XtraTabControl, Navigation Frame, Tab Pane, Tabbed Groups of Layout Control, or Tabbed View.
    They help you improve the load time due to the following .NET specificity - A control's handle is created only when the control becomes visible (this operation takes some time). When the control is placed on a tab, its handle is created only when the tab is activated.
  • Consider using the Deferred Load feature to show contents in documents dynamically. You will handle a dedicated event (for example, QueryControl) to supply contents. The deferred load will save you a few more seconds.

Tip

  • You can display a form after all controls are initialized. For this, override the main form's ShowMode property so it returns the FormShowMode.AfterInitialization value:
C#
protected override FormShowMode ShowMode { get { return FormShowMode.AfterInitialization; } }

Issue 3: A form, user control, or application module works slowly

Cause: "Heavy" logic/complex code execution.

Solution: Find and optimize the code that takes a lot of time to execute.

How to find a bottleneck.

  • Comment out your code line by line until you find code lines that take the most time to execute. Pay special attention to events you are using and comment them out in the first place. Specific events of our components can raise multiple times. The execution of complex code when a control draws its elements (for instance, in a GridView.CustomDrawCell event handler), or the control queries for cell values (for instance, in a GridView.CustomUnboundColumnData event handler) will slow down the application performance.
  • Use a performance profiler tool (the built-in VS one, or dotTrace, or any another) to measure your application performance and find the bottleneck.

How to optimize your code.

  • Avoid executing complex code in event handlers that are raised multiple times;
  • Use common techniques such as caching or executing heavy logic in a background thread.

If you face difficulties with code optimization and cannot find a way to avoid complex code execution in event handlers that are raised multiple times, feel free to create a ticket and describe the issue and scenario in greater detail.

Cause: Data-access operations take too much time.

Solution: Use steps from the previous section to find a place that takes much time to execute.

If you determined that a data access operation is slow, consider using SQL Server Profiler and similar database performance profiling tools depending on the db engine you are using. This approach is described in detail in the How to measure and improve application performance article.

Cause: An unhandled exception is thrown in code that is executed multiple times (e.g. in a control's custom painting event).

Solution: Enable exception handling, catch an exception, determine its cause, and fix it.

Please refer to the first section of the How to investigate an issue and determine why it occurs in your project article to learn how to resolve issues related to unhandled exceptions.

Issue 4: An application works fast locally but operates slowly in a remote environment.

Cause: The issue may occur because remote clients constantly take snapshots of an application. A large number of visual elements may affect the application's performance.

Solution: Disable optional visual effects.

Please refer to the Disable skins and visual effects section in the WinForms Tips & Tricks - Boosting Application Performance blog post.

In addition, set the WindowsFormsSettings.OptimizeRemoteConnectionPerformance property to DefaultBoolean.True to enable the remote connection optimization.

Issue 5: A form or its controls flicker when the form is displayed

Cause: All controls including the form itself aren't initialized at once. Instead, the initialization process is split into several stages. If long-running code is executed during your form's initialization, you can see a noticeable delay between these stages.

Solution.

You can display the form after it is completely initialized. To do this, override the ShowMode property, so it returns the FormShowMode.AfterInitialization value:

C#
protected override FormShowMode ShowMode { get { return FormShowMode.AfterInitialization; } }

Issue 6: Application performance is slow when there are Byte array columns (Image columns) in data-aware controls

Cause: Data-binding operation specifics cause many resource-consuming conversions.

There are some situations when column data at the database level does not have any direct prototypes in the .Net types system.
For example, when you work with images from a SQL data base, corresponding image data is loaded as byte arrays.
To display these images in cells of data-aware controls (Gantt Control, Data Grid, Tree List, Vertical Grid, etc.), the control converts byte arrays to raster or SVG images each time a corresponding cell is about to be painted.
Conversion of byte arrays to images is a resource-consuming operation and may lead to a severe performance penalty.

Solution: Use Columns with the Image data type instead of the byte array type.

Universal approach
You can disable the column's Visible option (GridColumn.Visible, etc) in a data-aware control to hide your byte array column. Then, add an unbound column to show Image values. To populate this column with 'Image' values, handle the CustomUnboundColumnData event. Please review the following example, which demonstrates it: How to create and populate an unbound column.

A collection of objects
Create a custom DTO class for database records with an Image value based on your data source data.
For this, you can use any standard technique. Then, you can populate a data-aware control with these modified records.

C#
public class Employee { public Employee(byte[] photoBytes) { using(var ms = new MemoryStream(photoBytes)) Photo = Image.FromStream(ms); } public Image Photo { get; } }

DataSet with DataTables
You can iterate through all DataTables in the target DataSet and convert all columns of the byte array columns to the Image type. Here is a possible implementation:

C#
public static void DataSetConvertByteToImage(DataSet ds) { foreach(DataTable tbl in ds.Tables) for(int i = tbl.Columns.Count - 1; i >= 0; i--) if(tbl.Columns[i].DataType == typeof(byte[])) DataSetConvertByteToImage(tbl, tbl.Columns[i]); } static void DataSetConvertByteToImage(DataTable tbl, DataColumn column) { string columnName = column.ColumnName; tbl.Columns.Add("temp", typeof(System.Drawing.Image)); foreach(DataRow row in tbl.Rows) row["temp"] = XtraEditors.Controls.ByteImageConverter.FromByteArray((byte[])row[column]); tbl.Columns.Remove(column); tbl.Columns["temp"].ColumnName = columnName; }

Pass your DataSet to the DataSetConvertByteToImage method to perform the conversion before assigning the DataSet to a data-aware control.

Diagnostic
To automatically detect badly configured columns, invoke the WindowsFormsSettings.ForcePaintApiDiagnostics method when your application starts:

C#
DevExpress.XtraEditors.WindowsFormsSettings.ForcePaintApiDiagnostics(DevExpress.Utils.Diagnostics.PaintApiDiagnosticsLevel.Throw);

When the diagnostic is enabled, the ByteArrayToImageConversionWarning exception will be thrown for each problematical case.

Issue 7. Visual Studio designer operates slowly or freezes

Solution

Please refer to the corresponding section in the following article for possible causes of the issue and solutions: DevExpress WinForms Troubleshooting - Visual Studio Design Time.

The issue is not on the Known Issues list

If the issue you faced is not described above, try the following steps to resolve it.

Steps

  • Use the tips from the WinForms Tips & Tricks - Boosting Application Performance blog post.
  • Use any performance profiler (for example, the built-in VS profiler, or dotTrace) to measure your application performance and find the bottleneck. If the profiler reveals that our code operates slowly, please create a new ticket in our Support Center and share performance profiler results and the problematic project that illustrates the issue.
  • Look for similar issues, errors, and solutions on the web, Stack Overflow or in our Search Engine.
  • If you could not find any information about the error on the web or in our Support Center and resolve the issue, please post a new ticket in our Support Center and share as much information as possible (performance profiler results, steps to reproduce, a project where the issue is reproducible). This information will help us determine the cause of the issue in the fastest and most straightforward way.

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.