A maneira mais concisa e adequada de evitar erro de operação cruzada?

Eu não sou muito bom em delegados e não entendo o que está acontecendo sob o capô. Eu recebo ocross thread operation erro ao acessar itens de interface do usuário de um segmento diferente.

O que eu quero fazer é escrever uma função genérica em umUtility class para que eu possa passar qualquer método / bloco de código para a função. Eu posso fazer isso de várias maneiras como:

delegate void UpdateGui(Control c, Action action);
public static void Do(Control c, Action action)
{
    try
    {
        if (c.InvokeRequired)
        {
            UpdateGui updaterdelegate = new UpdateGui(Do);
            c.TopLevelControl.Invoke(updaterdelegate, new object[] { c, action });
        }
        else
            action();
    }
    catch (Exception ex)
    {
        //throw ex;
    }
}
public static void Do(Control c, Action action)
{
    try
    {
        if (c.InvokeRequired) 
        {
            c.TopLevelControl.Invoke((Action)delegate { Do(c, action); });
        }
        else
            action();
    }
    catch (Exception ex)
    {
        //throw ex;
    }
}
public static void Do(Control c, Action action)
{
    try
    {
        if (c.InvokeRequired)
        {
            c.TopLevelControl.Invoke(action);
        }
        else
            action();
    }
    catch (Exception ex)
    {
        //throw ex;
    }
}
public static void Do(Control c, Action action)
{
    try
    {
        if (c.InvokeRequired) 
        {
            c.TopLevelControl.Invoke(new MethodInvoker(() => action()));
        }
        else
            action();
    }
    catch (Exception ex)
    {
        //throw ex;
    }
}
public static void Do(Control c, Action action)
{
    try
    {
        if (c.InvokeRequired) 
        {
            c.TopLevelControl.Invoke(new MethodInvoker(delegate { action(); }));
        }
        else
            action();
    }
    catch (Exception ex)
    {
        //throw ex;
    }
}
public static void Do(Control c, Action action)
{
    try
    {
        if (c.InvokeRequired) 
        {
            c.TopLevelControl.Invoke((MethodInvoker)delegate { action(); });
        }
        else
            action();
    }
    catch (Exception ex)
    {
        //throw ex;
    }
}

Eu acredito que as abordagens 1 e 2 são essencialmente as mesmas, e 4, 5 e 6 também. Minhas perguntas são:

Qual é a diferença entre as abordagens (1 e 2), 3 e (4, 5 e 6)? Quero dizer, quais seriam os casos em que um lida / cuida de qual outro não?

Qual é a maneira correta de evitarcross thread operation erro, no sentido de lidar com todas as situações, de preferência concisas e legíveis?

questionAnswers(1)

yourAnswerToTheQuestion