Actualización de la interfaz de usuario desde un subproceso en segundo plano que se llama en un bucle en la interfaz de usuario principal cuando el subproceso finaliza

Tengo una aplicación de WinForms que está llamando a un método de clase de negocios que realiza una acción de trabajo pesado que toma aproximadamente 5 segundos para cada llamada. La forma principal llama a este método en un bucle. Este bucle puede correr desde 10 veces hasta tal vez hasta 10 mil veces.

La aplicación WinForms envía un parámetro a la clase de negocios y tiene un área para mostrar el tiempo necesario para cada llamada de método y el valor devuelto por el método. ¿Cómo informo a mi ventana principal y actualizo un área de texto en el formulario de ganancias principal con lo que el método ha devuelto para cada llamada?

Actualmente los datos vienen todos a la vez después de que todos los hilos hayan terminado. ¿Hay una manera de actualizar la interfaz de usuario para todas las iteraciones del bucle una vez que se realiza cada llamada? No me importa si se hace secuencialmente también.

La 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;

    }

La clase de negocios 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;
    }

Respuestas a la pregunta(1)

Su respuesta a la pregunta