Skip to main content

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:

Designer Sync Method Designer Async Method Viewer Sync Method Viewer Async Method
ReloadData ReloadDataAsync ReloadData ReloadDataAsync
SetDashboardState SetDashboardStateAsync SetDashboardState SetDashboardStateAsync
SetMasterFilter SetMasterFilterAsync SetMasterFilter SetMasterFilterAsync
ClearMasterFilter ClearMasterFilterAsync ClearMasterFilter ClearMasterFilterAsync
PerformDrillDown PerformDrillDownAsync PerformDrillDown PerformDrillDownAsync
PerformDrillUp PerformDrillUpAsync PerformDrillUp PerformDrillUpAsync
SetRange SetRangeAsync SetRange SetRangeAsync
GetItemData GetItemDataAsync GetItemData GetItemDataAsync
GetAvailableDrillDownValues GetAvailableDrillDownValuesAsync GetAvailableDrillDownValues GetAvailableDrillDownValuesAsync
GetAvailableFilterValues GetAvailableFilterValuesAsync GetAvailableFilterValues GetAvailableFilterValuesAsync
GetEntireRange GetEntireRangeAsync GetEntireRange GetEntireRangeAsync
MaximizeDashboardItem MaximizeDashboardItemAsync MaximizeDashboardItem MaximizeDashboardItemAsync
RestoreDashboardItem RestoreDashboardItemAsync RestoreDashboardItem RestoreDashboardItemAsync
ShowDataInspector ShowDataInspectorAsync ShowDataInspector ShowDataInspectorAsync

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.

Code example - Dashboard API methods in Async mode

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.

A table with events and their asynchronous counterparts

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.

    How to call async methods in UI thread

    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.

See Also