我尝试使用一个单独的线程修改视觉控件。我知道如何使用委托来避免像这样的跨线程异常。
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);
文档中的更多信息:如何声明、实例化和使用委托