Atualizando a interface do usuário de um thread de segundo plano que é chamado em um loop na interface do usuário principal quando o thread termina

Eu tenho um aplicativo WinForms que está chamando um método de classe de negócios que executa alguma ação pesada levando cerca de 5 segundos para cada chamada. O formulário principal chama esse método em um loop. Esse loop pode ser executado de 10 a 10 vezes.

O aplicativo WinForms envia um parâmetro para a classe de negócios e tem uma área para exibir o tempo gasto para cada chamada de método e qual o valor retornado pelo método. Como eu informo minha janela principal e atualizo uma área de texto no formulário principal com o que o método retornou para cada chamada?

Atualmente, os dados são todos de uma vez após todos os threads terem terminado. Existe uma maneira de atualizar a interface do usuário para todas as iterações do loop uma vez que cada chamada é feita? Eu não me importo se for feito sequencialmente também.

A forma

    HeavyDutyClass hd;
    public Form1()
    {
        InitializeComponent();
        hd = new HeavyDutyClass();
    }


    //BUTTON CLICK
    private void Start_Click(object sender, EventArgs e)
    {

        int filecount = 5000;  //BAD - opening 5000 threads! Any other approach?
        hd.FileProcessed += new EventHandler(hd_FileProcessed);


        var threads = new Thread[filecount];

        for (int i = 0; i < filecount; i++)
        {
            threads[i] = new Thread(() => { hd.LongRunningMethod(); });
            threads[i].Start();   
        }

    }

    //BUSINESS CLASS EVENT THAT FIRES WHEN BUSINESS METHOD COMPELTES
    void hd_FileProcessed(object sender, EventArgs e)
    {

        if (dgv.InvokeRequired)
        {
            dgv.Invoke((MethodInvoker)delegate { UpdateGrid(); });

        }
    }

    private void UpdateGrid()
    {
        dgv.Rows.Add(1);
        int i = dgv.Rows.Count;
        dgv.Rows [ i-1].Selected = true;
        dgv.FirstDisplayedScrollingRowIndex = i - 1;

    }

A classe de negócios HeavyDuty

    public event EventHandler FileProcessed;

    public HeavyDutyClass()
    {
    }

    protected virtual void OnMyEvent(EventArgs e)
    {
        if (FileProcessed != null)
        {
            FileProcessed(this, e);
        }
    }

    public bool LongRunningMethod()
    {
        for (double i = 0; i < 199990000; i++)
        {
            //time consuming loop
        }
        OnMyEvent(EventArgs.Empty);
        return true;
    }

questionAnswers(1)

yourAnswerToTheQuestion