Search code examples
c#multithreadingdelegatesinvoke

Difference between using delegate and non-delegate method as argument in Contol.Invoke to avoid cross thread exception


I try to use a separate thread modifing visual control. I know how to use delegate to avoid a cross thread exception like this.

delegate void LabelTextDelegate(string _String);

LabelTextDelegate LabelTextDelegate1;

private void Form1_Click(object sender, EventArgs e)
{
    LabelTextDelegate1 = new(LabelText);

    new Thread(Method1).Start();
}

void Method1()
{
    label1.Invoke(LabelTextDelegate1, "a"); // delegate
}

void LabelText(string _String)
{
    label1.Text = _String;
}

But the following code simpler works well too.

private void Form1_Click(object sender, EventArgs e)
{
    new Thread(Method1).Start();
}

void Method1()
{
    label1.Invoke(LabelText, "a"); // non-delegate method
}

void LabelText(string _String)
{
    label1.Text = _String;
}

What is the difference? Is the latter correct? If so, I know Control.Invoke needs a delegate as an argument and does it change non-delegate method to delegate internally?


Solution

  • Your "non-delegate method" is still using a delegate. It's using a method group conversion to a delegate type (in this case to Action<string>).

    Your code is equivalent to:

    void Method1()
    {
        label1.Invoke(new Action<string>(LabelText), "a");
    }
    

    In earlier versions of C#, the method group conversion wouldn't have succeeded as Delegate isn't a specific delegate type, but as of C# 10, a method group with exactly one overload has a "natural type".