Warning: this post contains elements of self promotion ;o)
I would probably use a splash form in this case. I wrote a blog post a while ago (triggered by this SO Q&A) about a thread-safe splash form that could be used together will long-running main form initializations.
In short the approach is to using ShowDialog, but to create and display the form on a separate thread so it doesn't block the main thread. The form contains a status message label (could of course be extended with a progressbar as well). Then there is a static class that provides thread-safe methods for displaying, updating and closing the splash form.
Condensed code samples (for commented code samples, check the blog post):
using System;
using System.Windows.Forms;
public interface ISplashForm
{
IAsyncResult BeginInvoke(Delegate method);
DialogResult ShowDialog();
void Close();
void SetStatusText(string text);
}
using System.Windows.Forms;
public partial class SplashForm : Form, ISplashForm
{
public SplashForm()
{
InitializeComponent();
}
public void SetStatusText(string text)
{
_statusText.Text = text;
}
}
using System;
using System.Windows.Forms;
using System.Threading;
public static class SplashUtility<T> where T : ISplashForm
{
private static T _splash = default(T);
public static void Show()
{
ThreadPool.QueueUserWorkItem((WaitCallback)delegate
{
_splash = Activator.CreateInstance<T>();
_splash.ShowDialog();
});
}
public static void Close()
{
if (_splash != null)
{
_splash.BeginInvoke((MethodInvoker)delegate { _splash.Close(); });
}
}
public static void SetStatusText(string text)
{
if (_splash != null)
{
_splash.BeginInvoke((MethodInvoker)delegate { _splash.SetStatusText(text); });
}
}
}
Example of usage:
SplashUtility<SplashForm>.Show();
SplashUtility<SplashForm>.SetStatusText("Working really hard...");
SplashUtility<SplashForm>.Close();