Frequently, you will have to create applications that perform time-consuming operations such as file downloads or complex calculations. These operations can cause the user interface to lock up and become unresponsive, thus leading to an unpleasant user experience. By using asynchronous action, you can enable time consuming operations to be run asynchronously, thus keeping the user interface responsive while the operations are run.

koossery.MVCwin provides a way to indicate that an action should be executed asynchronously. We can use configuration file or attribute configuration directly at the top of the action.

We are going to configure the Save action of the SaveController to be executed asynchronously.

First adds the following code to the Save action, this code is added just for testing purpose we are sure in your professional applications you won’t do that:

//this code is added just for testing purpose
System.Threading.Thread.Sleep(5000); 

Run the application and try to add a contact. Once the application is processing try to click the link “View list” on the save view, you will notice how the UI is frozen as shown on the figure below !:

FrozenSaveContact.png

To avoid UI to freeze, configure the Save action to be executed asynchronously. The configuration can be made using two different ways.

Configuration using attribute
At the top of the action you can add the Asynchronous attribute as shown below:

[Asynchronous]
 public IActionResult Save()
 {

Configuration using spring xml file
Since all controllers inherit from the ControllerBase they all have an internal string list that contains the list of all asynchronous actions. The configuration is made in the spring action configuration file and is shown below:

<object id="SaveController" type="ContactManager.controllers.contact.SaveController">
    <!--Injecting the concrete implementation-->
    <constructor-arg index="0">
      <ref object="ContactManagerLocal" />
    </constructor-arg>
    <property name="Session">
      <ref object="Session"/>
    </property>
    <property name="AsynchMethods">
      <list element-type="System.String">
        <value>Save</value>
      </list>
    </property>
  </object>

Once the configuration is made, the controller manager will execute the action asynchronously, the UI won’t freeze anymore.

To provide a high level of user experience we can subscribe to the background worker events. By subscribing the user will know when an asynchronous action is executing.

By default all views have a panel that contains a progress bar. Place the panel as you like on your view. An example is shown on the figure below:

SaveView_ProgressBar.png


Edit the BindDataToView on the SaveView so that it looks like the following:

public override void BindDataToView()
{
    //Retrieving the SaveViewData
    SaveViewData saveView = this.GetSessionData(typeof(SaveViewData).Name) as SaveViewData;

    //Initializing Data Source
    contactBindingSource.DataSource = saveView.Contact;

    
    //Retrieving the ControllerBase
    ControllerManager manager = this.ControllerManager as ControllerManager;

    //Subscription to events
    manager.BgAsyncMethods.ProgressChanged += new ProgressChangedEventHandler(BgAsyncMethods_ProgressChanged);
    manager.BgAsyncMethods.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BgAsyncMethods_RunWorkerCompleted);
}

Adds the BgAsyncMethodsProgressChanged and BgAsyncMethodsRunWorkerCompleted methods:

void BgAsyncMethods_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    //hide the progress bar
    plLogin.Visible = false;
}

void BgAsyncMethods_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    if (!plLogin.Visible) plLogin.Visible = true;
    plLogin.Refresh();
}


Run the application and try to create a new contact. You should obtain the result as shown on the figure bellow:

SaveView_Asynchronous.png

Last edited Jun 22, 2009 at 11:36 PM by koossery, version 2

Comments

No comments yet.