Other DevExpress WinForms Cheat Sheets
This article contains information on how to perform the following tasks:
- Update data from non UI threads
- Load data in background
- Handle frequently updated data
These recommendations apply to all DevExpress data-aware controls (Gantt Control, Data Grid, Tree List, Vertical Grid, etc.).
Thread-safe operations
Any visual .NET control has only four thread-safe methods: Invoke, BeginInvoke, EndInvoke, and CreateGraphics (if a handle has been created). The following operations, when invoked from a non-UI thread (a thread where these controls were not created), are not supported and may lead to unexpected results and errors:
- Modify data sources
- Access (read and modify) values of the control's properties
- Invoke the control's methods
- Access controls' columns, rows, and other elements
- Read and modify cell values (for example, ~GetCellValue, ~GetCellDisplayText and ~SetCellValue)
Use the standard thread-safe call techniques described in the following MSDN article to safely access controls and their elements:
How to: Make Thread-Safe Calls to Windows Forms Controls.
Best Practices
Update the data source using thread-safe operations
To handle data changes that come from a non UI thread, you can create two instances of your data source. Assign one instance to the data-aware control in the UI-thread and use the second data source instance in non UI threads. Implement a thread-safe synchronization mechanism to keep data in these two data sources in sync.
Take a look at the following example:
Updating a Grid datasource from a separate thread
Update the data source using RealTimeSource (the data-aware control is read-only).
If the data-aware control needs to be read-only, you can use the RealTimeSource component to update the control from non-UI threads. This component serves as a bridge between an underlying data source and the data-aware control. You can update the underlying data source from various threads directly - the RealTimeSource component will maintain event marshaling between these threads. It also merges changes to achieve better performance. The control stays responsive even if there are thousands of changes per second in the underlying data source.
The RealTimeSource component is a perfect solution when you need to work with frequently updated data.
Background data load
To load data in a background thread, bind a data source to the data-aware control only after it has been completely loaded. The key thing here is to assign the data source to the target control or copy the data loaded in the background thread to an existing data source in a thread-safe manner. You can use Asynchronous programming with async and await for this. You may also want to display an Overlay Form over the target data-aware control to indicate that data is being loaded.
You can find a complete project (BackgroundDataLoad_Example.zip) in the attachments.
C#public partial class Form1 : RibbonForm {
public Form1() {
InitializeComponent();
gridControl.Load += GridControl_Load;
}
private void GridControl_Load(object sender, EventArgs e) {
LoadDataAsync();
}
async void LoadDataAsync() {
IOverlaySplashScreenHandle handle = null;
try {
handle = SplashScreenManager.ShowOverlayForm(gridControl);
gridControl.DataSource = await Task.Run(GetData);
}
catch (Exception ex) { }
finally {
SplashScreenManager.CloseOverlayForm(handle);
}
}
IList GetData() {
Thread.Sleep(3000);
return SpaceObject.LoadData();
}
}
You may wish to refer to the following example in our Grid Main Demo demonstrating another implementation of this approach:
Load details asynchronously
Load data by small portions on demand in background
To load data to the GridControl or the SearchLookUpEdit you can use Instant Feedback Data Sources (asynchronous server mode data sources). These data sources load data in a background thread so that the GUI remains responsive. Please refer to the following articles for more information:
Large Data Sources: Server and Instant Feedback Modes
Display Data From a Large Database or Data Storage