帮助在调用新操作时理解 C# 语法

发布于 2024-11-19 02:43:33 字数 916 浏览 3 评论 0原文

我是 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;
      }));
}

我确实难以理解的代码片段是:

label1.Invoke(new Action(() =>
         {
              label1.Text = Line;
          }));

有人可以分解它在做什么吗?我确信这没什么复杂的,只是我以前从未见过类似的东西。真正让我困惑的语法是 ()=> 新操作指向下面的代码或其他东西?

I am new to c# and do not understand the syntax of invoking a new action or even what an action is. From my understanding in Port1_DataReceived, I have to create an action because I am in a new tread... Can anyone elaborate on why I need to do this?

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

The code snip that I am really having trouble understanding is:

label1.Invoke(new Action(() =>
         {
              label1.Text = Line;
          }));

Can someone break down what this is doing.. I am sure it is nothing to complicated, just that I have never seen anything like it before. The syntax that is really holding me up is ()=> the new action is pointing to the code below or something??

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

睫毛上残留的泪 2024-11-26 02:43:33

这使用称为“lambda 表达式”的东西来创建与 Action 构造函数所需的签名相匹配的匿名委托。

您可以实现相同的效果,如下所示:

label1.Invoke(SetText);
...
public void SetText() { label1.Text = Line; }

或像这样:

label1.Invoke(new Action(SetText));
...
public void SetText() { label1.Text = Line; }

或像这样:

label1.Invoke(new Action(delegate() { label1.Text = Line; }));

或像这样:

label1.Invoke(delegate() { label1.Text = Line; });

或像这样:

label1.Invoke(() => label1.Text = Line);

这些大多只是语法快捷方式,以便更容易地表示动作。

请注意,lambda 表达式通常带有参数。当只有一个参数时,括号是可选的:

list.ToDictionary(i => i.Key);

当没有参数或多个参数时,括号是必需的,以使您在做什么一目了然。因此,() =>

This uses something known as a "lambda expression" to create an anonymous delegate that matches the signature expected by the Action constructor.

You could achieve the same effect like this:

label1.Invoke(SetText);
...
public void SetText() { label1.Text = Line; }

or like this:

label1.Invoke(new Action(SetText));
...
public void SetText() { label1.Text = Line; }

or like this:

label1.Invoke(new Action(delegate() { label1.Text = Line; }));

or like this:

label1.Invoke(delegate() { label1.Text = Line; });

or like this:

label1.Invoke(() => label1.Text = Line);

These are mostly just syntactic shortcuts to make it easier to represent an action.

Note that lambda expressions often have parameters. When there is only one parameter, the parentheses are optional:

list.ToDictionary(i => i.Key);

When there are no parameters or multiple parameters, the parentheses are necessary to make it obvious what you're doing. Hence, the () =>.

﹂绝世的画 2024-11-26 02:43:33

让我们一点一点地分解它。

label1.Invoke(

这是 Control.Invoke 方法。它的定义如下:

public Object Invoke(Delegate method);

在拥有控件的基础窗口句柄的线程上执行指定的委托。

这意味着您给它一个要调用的方法的引用,Control.Invoke 将确保它在 UI 线程上被调用(这将防止更新 UI 时出现跨线程异常)。 ) 它采用默认的 Delegate 作为参数,这意味着您需要向其传递一个不带参数且没有返回值的方法。这就是 System.Action 的位置委托类型出现:

public delegate void Action();

使用 lambda 表达式,我们可以创建一个内联的 Action 委托。首先,我们指定委托类型:

label1.Invoke(new Action(

然后,我们将开始 lambda 语法。一组空括号表示 lambda 函数不带参数,后面的“箭头”表示我们要启动该方法:

label1.Invoke(new Action(() =>

现在,因为 lambda 方法没有返回值(但必须执行一条语句),所以我们需要将我们想要在 UI 线程上执行的代码括在大括号中:

label1.Invoke(new Action(() =>
{
    label1.Text = Line;
}

关闭剩余的括号,您就得到了完整的、完成的语句。

label1.Invoke(new Action(() =>
{
    label1.Text = Line;
}));

Let's break it down piece by piece.

label1.Invoke(

This is the Control.Invoke method. Here's how it's defined:

public Object Invoke(Delegate method);

Executes the specified delegate on the thread that owns the control's underlying window handle.

What that means is that you give it a reference to a method to call, and Control.Invoke will make sure it gets called on the UI thread (which will prevent cross-threading exceptions while updating the UI.) It takes a default Delegate as a parameter, which means you need to pass it a method that takes no parameters and has no return value. That's where the System.Action delegate type comes in:

public delegate void Action();

Using lambda expressions, we can create an Action delegate inline. First, we specify the delegate type:

label1.Invoke(new Action(

Then, we will begin the lambda syntax. An empty set of parenthesis will denote that the lambda function takes no parameters, and an "arrow" afterwards shows that we want to start the method:

label1.Invoke(new Action(() =>

Now, because the lambda method has no return value (but must execute a statement) we need to surround the code we want to execute on the UI thread in curly braces:

label1.Invoke(new Action(() =>
{
    label1.Text = Line;
}

Close up the remaining parenthesis, and you have the full, finished statement.

label1.Invoke(new Action(() =>
{
    label1.Text = Line;
}));
可爱咩 2024-11-26 02:43:33

通常,当您想要向 GUI 添加某些内容并且您正在另一个线程中工作时,您需要执行称为“调用”的操作。

要进行调用,您可以使用控件Invoke方法或诸如应用程序调度程序之类的方法,这些方法通常采用操作< /代码>。 Action 顾名思义,就是要执行的事情。

在您的情况下,您要做的是向 GUI 上的元素添加一行文本,因此您需要做的是创建一个 Action (匿名方法)并在此操作您只需说“将此添加到我的控件”即可。然后您调用它以避免跨线程问题。

()=> 只是创建方法的“捷径”(lambda 方式),即匿名。这意味着除了创建匿名方法的上下文之外,您无法从任何地方调用它。

您还可以调用“全局”方法,它不必是匿名方法。

Generally when you want to add something to you GUI and you are working from another thread you need to do something called Invocation.

To make an invocation you use either a Controls Invoke method or the something like an Application Dispatcher, these methods generally take an Action. An Action is just what it sounds like, something that is to be performed.

In your case what you are doing is that you want to add a line of text to an element that lives on your GUI, so what you need to do is to create an Action ( anonymouse method ) and in this action you just say "Add this to my Control". And then you Invoke this to avoid cross-threading problems.

()=> is just a "shortcut"(lambda way) to create a method, that is anonymous. This means that you can't call this from anywhere but the context of where you created the anonymous method.

You can also Invoke a "global" method, it doesn't have to be an anonymous method.

风蛊 2024-11-26 02:43:33

Action 是一种委托类型,换句话说,它封装了一个函数。具体来说,Action 封装了一个返回 void 的函数,而 Func 则封装了一个带有返回值的函数。它们很像 C++ 中的函数指针——本质上是对函数的引用,即封装行为的一种方式。

.Invoke() 方法接受 Action 委托并运行它指向的函数。在这种情况下,它指向的函数是 lambda 表达式:

() => { label1.Text = Line }

最初的括号表示传递到函数中的任何参数。在这种情况下,没有参数,因此括号为空。例如,如果您想传递两个字符串,您可以这样做:

var action = new Action<string, string>( (x, y) => { // use x and y }

“=>”后面的内容表达式本质上是函数的主体。您可以访问此正文范围内括号中指定的变量。

总而言之,这是一种动态创建匿名函数的快速方法,本质上相当于以下内容:

public void SetLine()
{
   label1.Text = Line; 
}

因此,您还可以通过执行以下操作来创建该 Action 对象:

var action = new Action(SetLine) 

您传入要封装的方法的名称,而不是传入一个 lambda。传入的内容称为“方法组”。

An Action is a delegate type, in other words it encapsulates a function. Specifically an Action encapsulates a function that returns void, whereas for instance a Func would encapsulate a function with a return value. These are alot like a function pointers in C++ -- essentially a reference to a function ie a way to encapsulate behavior.

The .Invoke() method takes the Action delegate and runs the function it points to. In this case the function it points to is the lambda expression:

() => { label1.Text = Line }

The initial parentheses denote any parameters being passed into the function. In this case there are no parameters so the parentheses are empty. For example if you wanted to pass in two strings, you would do:

var action = new Action<string, string>( (x, y) => { // use x and y }

Whatever follows the '=>' expression is essentially the body of the function. You have access to the variables specified in the parentheses inside the scope of this body.

Altogether this is a quick way to create an anonymous function on the fly that essentially is equivalent to the following:

public void SetLine()
{
   label1.Text = Line; 
}

As such you could also create that Action object by doing:

var action = new Action(SetLine) 

where you are passing in the name of the method to encapsulate instead of passing in a lambda. Whats passed in is known as a 'Method Group'.

絕版丫頭 2024-11-26 02:43:33

行动是代表。 Label1.Invoke() 用于执行代码 label1.Text = line 以避免跨线程操作。 DataReceived 事件的事件处理程序在 UI 线程之外的不同线程上执行。 label1.Invoke() 将在 UI 线程中执行代码。

Action is a delegate. Label1.Invoke() is being used to execute the code label1.Text = line to avoid Cross Threading Operation. the event handler for DataReceived event is executing on a different thread other than UI thread. label1.Invoke() will execute the code in UI thread.

往事风中埋 2024-11-26 02:43:33

这将生成一个匿名方法(准确地说是 lambda)并传递该方法到调用方法。 Lambda 是一种让代码只需要一次的好方法,因此您不需要大量辅助方法只做一件事。

This is generating an anonymous method (a lambda, precisely) and passing that to the invoke method. Lambdas are a great way to have code you only need once so you don't need a lot of helper methods doing one thing only.

沧笙踏歌 2024-11-26 02:43:33

这可确保标签的文本在 UI 线程中运行。 Port1_DataReceived 事件可能会在后台线程中运行,并且不应从后台线程设置标签的文本值。这可以防止这种情况发生。

This is ensuring that the label's text is running in the UI thread. The Port1_DataReceived event will likely run in a background thread, and the Label's text value should not be set from background threads. This prevents that from happening.

吻风 2024-11-26 02:43:33

我不知道 label1 是什么,但可以理解为:

label1 是一个操作,它接收另一个操作作为参数。当它调用在参数中收到的操作时,它会做某事。

现在,我已经读过,我可能是一个问题 - label1 不能是一个操作。因为它只是一个控件,在这里设置:label1.Text = Line;

您的应用程序出现错误;

编辑

抱歉,请阅读:

http://msdn .microsoft.com/en-us/library/zyzhdc6b.aspx

在拥有控件的基础窗口句柄的线程上执行指定的委托。

代码是正确的。

I don't know what the label1 is, but the could could be read as:

label1 is an Action, that recieves another action as parameter. It does something and when it calls action recieved in argument.

Now, I've read that and I could be a problem - label1 could not be an Action. As it is just a control which set here: label1.Text = Line;

You have an error in your app;

EDIT

Sorry, just read that:

http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

Executes the specified delegate on the thread that owns the control's underlying window handle.

Code is correct.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文