Asynchronous tasks on Winform
Posted on : 11-05-2009 | By : manitra | In : C#, Developpement, WinForm
2
The problem
When you create winform applications, doing tasks in the background is essential to avoid user frustation. Unfortunatly, it could make you write a lot more code. Here are some utility methods that reduce the complexity of asynchronous calls within windows forms.
Within you base class
You probably have a common base class for all your UI components. Add these methods :
-
namespace TestWinForm
-
{
-
public class BaseForm : Form
-
{
-
// Execute some code in async mode.
-
// When it's done, it calls the nextStep delegate, eventually with
-
// an exception catched during the main action.
-
protected virtual void Async(Action action, Action nextStep)
-
{
-
new Thread(delegate()
-
{
-
Exception exception = null;
-
try
-
{
-
action();
-
}
-
catch (Exception ex)
-
{
-
exception = ex;
-
}
-
ThreadSafe(() => { nextStep(exception ); });
-
}).Start();
-
}
-
-
// This allows a sub class to easily run a method within
-
// an UI thread without the need of creating multiple
-
// delegate signatures for each method signatures
-
protected virtual void ThreadSafe(MethodInvoker method)
-
{
-
if (InvokeRequired)
-
Invoke(method);
-
else
-
method();
-
}
-
}
-
}
Within your UI classes
Now the only thing you need to do is to encapsulate the methode content with the Async() method :
namespace TestWinForm
-
{
-
public partial class MainForm : BaseForm
-
{
-
public MainForm()
-
{
-
InitializeComponent();
-
}
-
-
// Here is the async trick :
-
// – UI will NOT freeze,
-
// – you can add beautifull animated gifs
-
private void button1_Click(object sender, EventArgs e)
-
{
-
DateTime? result = null;
-
Async(
-
() =>
-
{
-
result = GetComplexDate();
-
},
-
(ex) =>
-
{
-
if (ex == null)
-
textBox1.Text = result.Value.ToShortDateString();
-
else
-
textBox1.Text = ex.Message;
-
}
-
);
-
}
-
-
// This is the slow, data-intensive task :p
-
private DateTime? GetComplexDate()
-
{
-
Thread.Sleep(3000);
-
return DateTime.Now;
-
}
-
}
-
}
The traditional way
Just in case you didn’t get it. This is what you should NOT DO:
// This was traditional way :
-
// – UI will freeze until during 3 second …
-
// – you users will complain
-
// avoid this !
-
private void button1_Click2(object sender, EventArgs e)
-
{
-
try
-
{
-
textBox1.Text = GetComplexDate().ToShortDateString();
-
}
-
catch (Exception ex)
-
{
-
textBox1.Text = ex.Message;
-
}
-
}
Happy coding !

