Migrate WinForms Dashboard Application to Asynchronous Mode
- 4 minutes to read
Asynchronous mode increases the performance and responsiveness of your application. Dashboard items appear sequentially as they are ready. Data that is processed first appears without waiting for more time-consuming calculations.
Switch to Asynchronous Mode
Set the Dashboard Viewer’s or Designer’s AsyncMode
property to true:
Property | Value |
---|---|
DashboardViewer.AsyncMode | true |
DashboardDesigner.AsyncMode | true |
Assign the AsyncMode property in the Visual Studio Designer (InitializeComponent code) or in the form’s constructor code. At runtime switch modes when the data loading is completed.
Use Asynchronous Methods
Replace synchronous methods with their async analogues based on the following table:
In asynchronous mode, synchronous methods work in the same manner as in the synchronous mode, but data is loaded asynchronously. When the next line of code executes, data may be outdated, because the data loading process is not finalized.
This is the reason for replacing synchronous methods with their asynchronous analogues. Asynchronous methods allow you to wait for data loading to complete before execution.
The code snippets below illustrate our recommendations on migrating from synchronous to asynchronous methods.
// The Func1 function returns no data, so it has the same result in Async mode.
// However, we recommend the asynchronous analogue for better performance.
//void Func1(){
// ...
// viewer.SetMasterFilter(...);
//}
async void Func1(){
...
await viewer.SetMasterFilterAsync(...);
}
// The Func2 function in synchronous mode returns the data after the master filter is applied.
// In asynchronous mode the GetItemData method returns data prior to master filtering.
// In asynchronous mode We recommend the SetMasterFilterAsync and GetItemDataAsync methods
// to return data after the master filter is applied.
//MultiDimensionalData Func2(){
...
// viewer.SetMasterFilter(name...);
// var data = viewer.GetItemData(name);
// return data;
}
async Task<MultiDimensionalData> Func2(){
...
await viewer.SetMasterFilterAsync(name...);
var data = await viewer.GetItemDataAsync(name);
return data;
}
Load Data in Asynchronous Events
The DataLoading and ValidateCustomSqlQuery events in asynchronous mode operate in the same manner as in synchronous mode. If you switch to their asynchronous analogues, an application can gain performance benefits because event handlers are executed in a different thread. The UI thread is not blocked, but objects in the UI thread are inaccessible.
The DashboardDesigner.AsyncDataLoading and DashboardDesigner.DataLoading events in asynchronous mode may occur multiple times while you design a dashboard and change the dashboard object model. To improve performance, do not call time-consuming methods in the event handler.
Important
Any code that directly accesses controls and other objects created in the UI thread should be removed from the async event handlers.
Handle the AsyncDataLoading and AsyncValidateCustomSqlQuery events instead of their counterparts, as listed in the following table:
Designer Event | Designer Async Event | Viewer Event | Viewer Async Event |
---|---|---|---|
DashboardDesigner.DataLoading | DashboardDesigner.AsyncDataLoading | DashboardViewer.DataLoading | DashboardViewer.AsyncDataLoading |
DashboardDesigner.ValidateCustomSqlQuery | DashboardDesigner.AsyncValidateCustomSqlQuery | DashboardViewer.ValidateCustomSqlQuery | DashboardViewer.AsyncValidateCustomSqlQuery |
Use the Initialized Event
The Initialized event indicates that you can safely access the dashboard and its items in asynchronous mode. Handle this event to call the DashboardViewer and DashboardDesigner methods that you normally call in the form’s constructor.
Designer Event | Viewer Event |
---|---|
DashboardDesigner.Initialized | DashboardViewer.Initialized |
Tip
The Initialized event occurs in asynchronous and synchronous modes. You can move the code that calls the DashboardViewer or DashboardDesigner methods to the event handler, and toggle between Async and Sync modes without changing code.
Restrictions
In asynchronous mode, take into account the following restrictions:
Interactivity events - DrillDownPerformed, MasterFilterSet, DashboardItemSelectionChanged - occur immediately after the user action, but before the data are loaded or updated in dashboard items. When you use these events in asynchronous mode, you can get the outdated data. Use the asynchronous counterparts instead (DrillDownPerformedAsync, MasterFilterSetAsync, DashboardItemSelectionChangedAsync).
Do not block UI thread while executing the Asynchronous API methods.
Correct:
async void OnButtonClick(object sender, EventArgs e) { MultiDimensionalData data = await dashboardDesigner1.GetItemDataAsync("gridDashboardItem1"); MessageBox.Show(data != null ? data.GetAxisPoints(DashboardDataAxisNames.DefaultAxis).Count.ToString() : "is null"); }
Incorrect:
void OnButtonClick(object sender, EventArgs e) { MultiDimensionalData data = null; dashboardDesigner1.GetItemDataAsync("gridDashboardItem1") .ContinueWith((Task<MultiDimensionalData>task) => { data = task.Result; }).Wait(); MessageBox.Show(data != null ? data.GetAxisPoints(DashboardDataAxisNames.DefaultAxis).Count.ToString(): "is null"); }
The DashboardSqlDataSource.LockUIOnDataLoading and DashboardExcelDataSource.LockUIOnDataLoading properties have no effect because in asynchronous mode the data source loads data in the background, and the UI thread is not locked.