Tuesday, 20 August 2013

Show wait cursor when all work is synchronous

Show wait cursor when all work is synchronous

In my Winforms application when you start an operation it may or may not
be done asynchronously. In the case that the work is all done
synchronously, I cannot get the wait cursor to show up using the same
approach I use when the work is done asynchronously.
Here's an example showing the issue:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var t = ButtonClick(button1, DoWorkAsync1);
}
private void button2_Click(object sender, EventArgs e)
{
var t = ButtonClick(button2, DoWorkAsync2);
}
private async Task ButtonClick(Button btn, Func<Task> doWorkAsync)
{
// Disable the UI and show the wait cursor
btn.Text = "Working...";
btn.Enabled = false;
UseWaitCursor = true;
// Application.DoEvents(); // Inserting this causes the problem to
go away.
await doWorkAsync();
// Simulate an update of the UI taking a long time
Thread.Sleep(2000);
// Renable the UI and stop showing the wait cursor
UseWaitCursor = false;
btn.Enabled = true;
}
private Task DoWorkAsync1()
{
// Work takes some time
return Task.Delay(2000);
}
private Task DoWorkAsync2()
{
// Work doesn't take any time, results are immediately available
return Task.FromResult<int>(0);
}
}
In this example:
Clicking button1 does show the Wait cursor (because the work is done
asynchronously).
Clicking button2 does not show the Wait cursor (because the work is all
done synchronously).
Clicking either button1 and button2 does result in the UI being disabled
as expected.
What is desired is that clicking either button1 or button2 should cause
the Wait cursor to be displayed for the entire interval between clicking
the button and the UI update work being completed.
Question:
Is there a way to solve this without inserting an Application.DoEvent (nor
anything equivalent that would cause message pumping to occur), or is it
only possible by pumping messages.
As an aside: why does the disabling of the control work correctly (unlike
the cursor).

No comments:

Post a Comment