Tnx!

Si, effettivamente ho trovato qualcosa riguardo l'Invoke ma per certi versi è un pò castrante, non riesco ad usarlo come vorrei io.

In compenso con il Timer invece ho ottenuto qualcosa di funzionale e al contempo semplice.

Va comunque usato l'Invoke anche in questo caso altrimenti da l'eccezione cross-threading, ma è semplice.

codice:
        delegate void SetTextCallback(string text);

        private void button1_Click(object sender, EventArgs e)
        {
            System.Threading.Timer tm = new System.Threading.Timer(new TimerCallback(Esegui));
            tm.Change(2000, 0);
        }

        private void Esegui(object Tmr)
        {
            System.Threading.Timer timer = (System.Threading.Timer)Tmr;
            timer.Dispose();
            this.SetText("Eseguito");
        }

        private void SetText(string text)
        {
            if (this.textBox1.InvokeRequired)
            {
                SetTextCallback d = new SetTextCallback(SetText);
                this.Invoke(d, new object[] { text });
            }
            else
            {
                this.textBox1.Text = text;
            }
        }
Una volta premuto button1 viene avviato un Timer che attende 2 secondi prima di eseguire l'operazione su texBox1.

Durante questi 2 secondi l'applicativo risulta utilizzable e non rallentato.