Check before proceeding if the task in BackgroundWorker has completed
You can use ManualResetEvent to wait until background work is done. So, you can define in LoginForm as:

private static ManualResetEvent mre = new ManualResetEvent(false);


When background work is completed, you should change the state of mre from the thread method bw_DoWork and update appStatus:

mre.Set();


btn_login_Click should wait for mre instead of while loop:

mre.WaitOne();


The complete code:

public partial class LoginForm : Form
{
    private static BackgroundWorker bw = new BackgroundWorker();
    private static ManualResetEvent mre = new ManualResetEvent(false);

    enum status
    {
        Blank,
        Success,
        Error
    };

    public LoginForm()
    {
        InterimProceedings();
        InitializeComponent();
    }

    private void InterimProceedings()
    {
        bw.DoWork += new DoWorkEventHandler(bw_DoWork);
        bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);

        if (!bw.IsBusy)
        {
            bw.RunWorkerAsync();
        }
        else
        {
            throw new InvalidOperationException("BackgroundWorker is busy");
        }
    }

    private void bw_DoWork(object sender, DoWorkEventArgs e)
    {
      //  Time taking task
      //  Update appStatus
      appStatus = status.Success;
      mre.Set();
    }

    private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        if (!(e.Error == null))
        {
            this.lbl_status.Text = "Cannot proceed, Error occured";
            appStatus = status.Error;
        }
        else
        {
            this.lbl_status.Text = "Good to go...";
            appStatus = status.Success;
        }
    }

    private void btn_login_Click(object sender, EventArgs e)
    {
        mre.WaitOne();

        if(appStatus == status.Success)
        {
            // Proceed with intended work
        }

        else
        {
            // Pop-up error occurred
        }
    }
}




The check against e.Error on bw_RunWorkerCompleted should change for clarity:

if (e.Error == null)
{
    this.lbl_status.Text = "Good to go...";
}
else
{
    this.lbl_status.Text = "Cannot proceed, Error occured";
}




I can't probe this code right now... I hope it's ok.