Для решения этой задачи можно использовать async/await. Для того нужно сделать у вызываемой функции возвращаемый тип Task (или дженерик - Task<нужный тип>), и добавить ключевое слово async (в данном примере это метод Run()). В месте вызывания нужно добавить await. К методу из которого происходит вызов - тоже нужно добавить async (в данном примере это button1_Click, но ему Task добавлять не обязательно - этот метод вызывается синхронно).
private async void button1_Click(object sender, EventArgs e)
{
await Run();
}
public async Task Run()
{
var form = new Form2();
form.Show();
//Тут делаем нужную работу
form.Close();
}
В данном примере метод Run вызовется асинхронно, без блокировки основного потока. Он создаст окно, и при завершении окно закроется и поток будет уничтожен.