在Contol.Invoke中使用委托和非委托方法作为参数之间的区别,以避免跨线程异常



我尝试使用一个单独的线程修改视觉控件。我知道如何使用委托来避免像这样的跨线程异常。

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

但下面的代码simpler也能很好地工作。

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

有什么区别?后者正确吗?如果是,我知道Control.Invoke需要一个委托作为参数,它是否将非委托方法更改为内部委托?

您的"非委托方法";仍在使用委托。它使用方法将转换为委托类型(在本例中为Action<string>(。

您的代码相当于:

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

在C#的早期版本中,方法组转换不会成功,因为Delegate不是特定于委托类型,但在C#10中,只有一个重载的方法组具有";自然型";。

没有区别,只是第二个例子使用了C#2中的语法。

实例化委托:

LabelTextDelegate myDelegate = new LabelTextDelegate(LabelText);
// C# 2 provides a sugar syntax to instantiate a delegate.
LabelTextDelegate myDelegate = LabelText;

当您传递委托作为方法的参数时,情况是一样的:

void Method1(LabelTextDelegate labelText)
{
labelText.Invoke("a");
}

Method1(new LabelTextDelegate(LabelText));
// With the C# 2 sugar syntax
Method1(LabelText);

文档中的更多信息:如何声明、实例化和使用委托

最新更新