Everything should work the way you have it but hide f1 and display f2 this way:
this.Hide();
var frm2 = new f2();
frm2.Closed += (sender, args) => this.Close();
frm2.Show();
To give a more detailed answer:
public class Form1() : Form
{
    public Form1() {
        InitializeComponent();
    }
    private void Form1_Load(object sender, EventArgs e) {
        var worker = new BackgroundWorker();
        worker.DoWork += worker_DoWork;
        worker.RunWorkerCompleted += worker_RunWorkerCompleted;
        worker.RunWorkerAsync();
    }
    private void worker_DoWork(object sender, DoWorkEventArgs e) {
        Thread.Sleep(5000);
        // this is where you can load your data from file
    }
    private void worker_RunWorkerCompleted(
        object sender, RunWorkerCompletedEventArgs e) 
    {
        this.Hide();
        var frm2 = new Form2();
        frm2.Closed += (s, a) => this.Close();
        frm2.Show();
    }
}
So Form1 will start to load data using a background worker. When the data is loaded, the BackgroundWorker will fire the RunWorkerCompleted event. That event handler will hide Form1 instead of closing it, create Form2, add a handler for form2's Closed event so that closing Form2 will stop your application, and then shows Form2.