我是c#的新手,并不了解调用新操作的语法,甚至不了解操作是什么.根据我对Port1_DataReceived的理解,我必须创建一个动作,因为我正处于新的阶段...任何人都可以详细阐述我为什么需要这样做?
public Form1()
{
InitializeComponent();
SerialPort Port1 = new SerialPort("COM11", 57600, Parity.None, 8, StopBits.One);
Port1.DataReceived += new SerialDataReceivedEventHandler(Port1_DataReceived);
Port1.Open();
}
private void Port1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort Port = (SerialPort)sender;
string Line = "";
int BytestoRead = Port.BytesToRead;
Line = Port.ReadLine();
label1.Invoke(new Action(() =>
{
label1.Text = Line;
}));
}
Run Code Online (Sandbox Code Playgroud)
我真正理解的代码片段是:
label1.Invoke(new Action(() =>
{
label1.Text = Line;
}));
Run Code Online (Sandbox Code Playgroud)
有人可以分解这是做什么的......我相信这并不复杂,只是因为我以前从未见过这样的事情.真正阻碍我的语法是()=>新动作是指向下面的代码还是什么?
Str*_*ior 11
这使用称为"lambda表达式"的东西来创建一个与Action构造函数所期望的签名匹配的匿名委托.
你可以达到同样的效果:
label1.Invoke(SetText);
...
public void SetText() { label1.Text = Line; }
Run Code Online (Sandbox Code Playgroud)
或者像这样:
label1.Invoke(new Action(SetText));
...
public void SetText() { label1.Text = Line; }
Run Code Online (Sandbox Code Playgroud)
或者像这样:
label1.Invoke(new Action(delegate() { label1.Text = Line; }));
Run Code Online (Sandbox Code Playgroud)
或者像这样:
label1.Invoke(delegate() { label1.Text = Line; });
Run Code Online (Sandbox Code Playgroud)
或者像这样:
label1.Invoke(() => label1.Text = Line);
Run Code Online (Sandbox Code Playgroud)
这些大多只是语法快捷方式,以便更容易表示操作.
请注意,lambda表达式通常具有参数.当只有一个参数时,括号是可选的:
list.ToDictionary(i => i.Key);
Run Code Online (Sandbox Code Playgroud)
当没有参数或多个参数时,括号是必要的,以使你明白你正在做什么.因此,() =>.
让我们一块一块地分解它.
label1.Invoke(
Run Code Online (Sandbox Code Playgroud)
这是Control.Invoke方法.以下是它的定义:
public Object Invoke(Delegate method);
Run Code Online (Sandbox Code Playgroud)
在拥有控件的基础窗口句柄的线程上执行指定的委托.
这意味着你给它一个要调用的方法的引用,并Control.Invoke确保它在UI线程上被调用(这将在更新UI时防止交叉线程异常.)它将默认值Delegate作为参数,意味着你需要传递一个不带参数且没有返回值的方法.这是System.Action委托类型的来源:
public delegate void Action();
Run Code Online (Sandbox Code Playgroud)
使用lambda表达式,我们可以创建一个Action内联委托.首先,我们指定委托类型:
label1.Invoke(new Action(
Run Code Online (Sandbox Code Playgroud)
然后,我们将开始lambda语法.一组空括号将表示lambda函数不带参数,之后的"箭头"表示我们要启动方法:
label1.Invoke(new Action(() =>
Run Code Online (Sandbox Code Playgroud)
现在,因为lambda方法没有返回值(但必须执行一个语句),我们需要在大括号中围绕我们想要在UI线程上执行的代码:
label1.Invoke(new Action(() =>
{
label1.Text = Line;
}
Run Code Online (Sandbox Code Playgroud)
关闭剩余的括号,你就有了完整的语句.
label1.Invoke(new Action(() =>
{
label1.Text = Line;
}));
Run Code Online (Sandbox Code Playgroud)