If you're looking at using Tasks for asynchronous operations, here is an example of how to do it.
1. Progress Form. Has a label to provide the progress messages - you can swap this out for a progress bar. Code-behind to handle the updates:
public partial class ProgressForm: Form
{
public ProgressForm()
{
InitializeComponent();
}
public void SetMessage(string text)
{
labMessage.Text = text;
}
}
2. The calling form with the long running task:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
ShowProgressWindow();
await UnitOfWork().ConfigureAwait(false);
CloseProgressWindow();
}
private void CloseProgressWindow()
{
if (InvokeRequired)
{
Invoke((MethodInvoker)(CloseProgressWindow));
}
else
{
progress.Hide();
button1.Enabled = true;
}
}
private void ShowProgressWindow()
{
button1.Enabled = false;
progress.Show(this);
}
private readonly ProgressForm progress = new ProgressForm();
private readonly List<string> UpdateMessages = new List<string>
{
"Loading the fodder",
"Watering the seeds",
"Feeding the goats",
"Clipping the flowers",
"Smelling the roses",
"Closing the doors",
"Saving the changes",
"Done!"
};
private Task<bool> UnitOfWork()
{
var tcs = new TaskCompletionSource<bool>();
Task.Run(async () =>
{
for (int i = 0; i < 8; i++)
{
ProgressUpdate(UpdateMessages[i]);
await Task.Delay(1000).ConfigureAwait(false);
}
tcs.SetResult(true);
}).ConfigureAwait(false);
return tcs.Task;
}
private void ProgressUpdate(string updateMessage)
{
if (InvokeRequired)
Invoke((MethodInvoker)(() => ProgressUpdate(updateMessage)));
else
progress.SetMessage(updateMessage);
}
}