Developing Responsive User Interfaces (UI) using Asynchronous methods/delegates in C#

by Jagadish Pulakhandam on 11/10/2011 12:23:23 PM
Rated 0 from 0 votes
Brief: This article demonstrates on working with long running tasks in Windows Forms in an efficient manner (which resolves application being frozen from responding to user or the problematic "Not Responding" issue)
Posted to: Microsoft Windows Forms - Advanced
Add to DiggAdd to del.icio.usAdd to FURLAdd to RedditAdd to YahooAdd to BlinklistAdd to GoogleAdd to ma.gnoliaAdd to ShadowsAdd to Technorati

This article demonstrates the following:
  • A long running job (a simple loop which repeats 10000 times) updating Windows Forms user interface (UI)
  • Windows Forms application (UI) frozen due to long running job (leading to "Not Responding" issue)
  • Resolving the issue by implementing Asynchronous execution of the process.
  • Calling delegates asynchronously
  • Updating Windows Forms controls during asynchronous process
  • delegates using classic .NET style and using advanced lambda style
Screenshot:



Source Code:

01.using System;
02.using System.Collections.Generic;
03.using System.ComponentModel;
04.using System.Data;
05.using System.Drawing;
06.using System.Linq;
07.using System.Text;
08.using System.Windows.Forms;
09. 
10.namespace AsynchronousDemo
11.{
12.    public partial class Form1 : Form
13.    {
14.        public Form1()
15.        {
16.            InitializeComponent();
17.        }
18. 
19.        private void btnDoProcess_Click(object sender, EventArgs e)
20.        {
21.            //Every application starts with a thread (called main/UI thread)
22. 
23.            //the loop runs on main thread (also called as UI thread in Win Forms)
24.            for (int i = 0; i < 10000; i++)
25.            {
26.                //does the job, but freezes application till the loop completes (UI thread is too busy with loop)
27.                lblMsg.Text = i.ToString();
28.                txtMsg.Text = i.ToString();
29.            }
30.            //you will only see 10000 at the end (you will not see numbers being updated from 0 to 10000)
31.        }
32. 
33.        delegate void DoProcessDelegate();
34.        private void btnDoProcessWithoutFreeze_Click(object sender, EventArgs e)
35.        {
36.            DoProcessDelegate d = new DoProcessDelegate(DoProcess);
37.            //execute asynchronously
38.            d.BeginInvoke(null, null); //executes on UI thread but asynchronously ie., UI thread picks the changes eventually
39.        }
40. 
41.        public void DoProcess()
42.        {
43.            //controls on the UI thread cannot be modified directly in a delegate.
44.            //have to use delegates to update the controls
45.            for (int i = 0; i < 100000; i++)
46.            {
47.                //for classic .NET (see region down)
48.                //-----------------------------------
49.                //UpdateLabel(i);
50.                //UpdateTextBox(i);
51. 
52. 
53.                //advanced way using Lambda expressions and anonymous delegates
54.                Invoke(new MethodInvoker(() => lblMsg.Text = i.ToString()));
55.                Invoke(new MethodInvoker(() => txtMsg.Text = i.ToString()));
56.            }
57.        }
58. 
59. 
60.        #region for classic .NET
61. 
62.        delegate void UpdateLabelDelegate(int i);
63.        public void UpdateLabel(int i)
64.        {
65.            if (lblMsg.InvokeRequired)
66.            {
67.                UpdateLabelDelegate d = new UpdateLabelDelegate(UpdateLabel);
68.                this.Invoke(d, new object[] { i });
69.            }
70.            else
71.            {
72.                lblMsg.Text = i.ToString();
73.            }
74.        }
75. 
76. 
77.        delegate void UpdateTextBoxDelegate(int i);
78.        public void UpdateTextBox(int i)
79.        {
80.            if (txtMsg.InvokeRequired)
81.            {
82.                UpdateTextBoxDelegate d = new UpdateTextBoxDelegate(UpdateTextBox);
83.                this.Invoke(d, new object[] { i });
84.            }
85.            else
86.            {
87.                txtMsg.Text = i.ToString();
88.            }
89.        }
90. 
91.        #endregion
92.    }
93.}



Join the .NET Code Central Community and join the discussion!
Signing-up is FREE and quick. Do it now, we want to hear your opinion
0

Rated 0 from 0 votes ( login  to rate)
DotnetKicks DotnetKicksDe DotNetShoutout

Attachments / Source Code
You need to Login or Join for FREE to download the following