Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从SerialDataReceivedEventHandler写入文本框控件_C#_Winforms_Static_Controller - Fatal编程技术网

C# 从SerialDataReceivedEventHandler写入文本框控件

C# 从SerialDataReceivedEventHandler写入文本框控件,c#,winforms,static,controller,C#,Winforms,Static,Controller,我敢肯定,只有我做得不对 我有一个Form1,它有一个按钮,onclick可以调用serialConn.cs中名为connect()的方法 这很好,但是当收到数据时,我希望它打印在我的表单1的文本框中。。 但是,由于我的DataReceivedEvent()是一个静态的(我想我必须是吗?),我不能访问任何东西? 那么最好的方法是什么呢?您需要将表单实例传递给这个connect方法(从按钮的事件处理程序): 在串行连接中: public static bool connect(string com

我敢肯定,只有我做得不对

我有一个
Form1
,它有一个按钮,onclick可以调用serialConn.cs中名为
connect()
的方法

这很好,但是当收到数据时,我希望它打印在我的
表单1的
文本框中。。
但是,由于我的
DataReceivedEvent()
是一个
静态的
(我想我必须是吗?),我不能访问任何东西?
那么最好的方法是什么呢?

您需要将表单实例传递给这个connect方法(从按钮的事件处理程序):

在串行连接中:

public static bool connect(string comPort, Form1 whichForm) {
然后可以使用lambda函数并关闭其中的“whichForm”引用,如下所示:

但是,此外,您应该确保不从主线程以外的其他线程实际修改GUI——这是非常可能的,因为SerialPort类的性质很可能从另一个后台线程引发事件——因此this.Invoke(其他一些lambda)它封送在主线程上执行的特定操作

MSDN明确指出:

当从SerialPort对象接收数据时,在辅助线程上引发DataReceived事件。由于此事件是在次线程而不是主线程上引发的,因此尝试修改主线程中的某些元素(如UI元素)可能引发线程异常。如果需要修改主窗体或控件中的元素,请使用Invoke将更改请求发回,这将在适当的线程上完成工作

public static bool connect(string comPort, Form1 whichForm) {
    BTserial = new SerialPort(comPort, 9600, Parity.None, 8, StopBits.One);
    BTserial.Open();
    if (BTserial.IsOpen) {
        BTserial.DataReceived += (sender, e) => {
          Debug.WriteLine("Data Incomming!");
          // Check if Chars are received
          if (e.EventType == SerialData.Chars) {
              Debug.WriteLine("Chars!");
              // Create new buffer
              byte[] ReadBuffer = new byte[BTserial.BytesToRead];

              // Read bytes from buffer
              BTserial.Read(ReadBuffer, 0, ReadBuffer.Length);
              BTserial.DiscardInBuffer();

              // Encode to string
              string data = bytesToString(ReadBuffer);


              Action toBeRunOnGuiThread = () => whichForm.theTextBox.Text = data;

              // to guard yourself from all evil
              // you could check to see if it is needed to
              if (whichForm.InvokeRequired) 
                // marshal the call to the action all the way to the GUI thread
                whichForm.Invoke(toBeRunOnGuiThread);
              else
                // or, if we ARE on the GUI thread already, just call it from this thread
                toBeRunOnGuiThread();

              ReadBuffer = null;
              data = null;
          }
    };
        return true;
    } else {
        return false;
    }
}

您需要将表单实例传递到此连接方法(从按钮的事件处理程序):

在串行连接中:

public static bool connect(string comPort, Form1 whichForm) {
然后可以使用lambda函数并关闭其中的“whichForm”引用,如下所示:

但是,此外,您应该确保不从主线程以外的其他线程实际修改GUI——这是非常可能的,因为SerialPort类的性质很可能从另一个后台线程引发事件——因此this.Invoke(其他一些lambda)它封送在主线程上执行的特定操作

MSDN明确指出:

当从SerialPort对象接收数据时,在辅助线程上引发DataReceived事件。由于此事件是在次线程而不是主线程上引发的,因此尝试修改主线程中的某些元素(如UI元素)可能引发线程异常。如果需要修改主窗体或控件中的元素,请使用Invoke将更改请求发回,这将在适当的线程上完成工作

public static bool connect(string comPort, Form1 whichForm) {
    BTserial = new SerialPort(comPort, 9600, Parity.None, 8, StopBits.One);
    BTserial.Open();
    if (BTserial.IsOpen) {
        BTserial.DataReceived += (sender, e) => {
          Debug.WriteLine("Data Incomming!");
          // Check if Chars are received
          if (e.EventType == SerialData.Chars) {
              Debug.WriteLine("Chars!");
              // Create new buffer
              byte[] ReadBuffer = new byte[BTserial.BytesToRead];

              // Read bytes from buffer
              BTserial.Read(ReadBuffer, 0, ReadBuffer.Length);
              BTserial.DiscardInBuffer();

              // Encode to string
              string data = bytesToString(ReadBuffer);


              Action toBeRunOnGuiThread = () => whichForm.theTextBox.Text = data;

              // to guard yourself from all evil
              // you could check to see if it is needed to
              if (whichForm.InvokeRequired) 
                // marshal the call to the action all the way to the GUI thread
                whichForm.Invoke(toBeRunOnGuiThread);
              else
                // or, if we ARE on the GUI thread already, just call it from this thread
                toBeRunOnGuiThread();

              ReadBuffer = null;
              data = null;
          }
    };
        return true;
    } else {
        return false;
    }
}

不知道你的意思。我看到了在connect()方法中运行它的想法。但是不明白:
Action to berunguithread=()=>this.theTextBox.Text=data;调用(toberunguithread)。。。我在
(sender,e){
('=>'预期)的
{
上得到syntaxt错误我为我之前犯的错误感到抱歉..再看一看代码..我错误地认为connect方法是Form1类的一部分,它是一个实例方法。然后我意识到它不是该类的一部分,它属于serialConn,并且是静态的。尝试发送表单实例(此)从按钮的click事件处理程序到您的connect方法。我重新编辑了整个帖子。通过ToBerunguithread操作,我的意思是,实际触摸表单和文本框并不是问题的结束。您还需要以非常安全的方式更改Text属性。SerialPort类在b上运行命令后台线程。这样,用户界面将永远不会冻结。用户界面线程需要不受长作业的影响,才能处理鼠标单击之类的操作。但所有这些都是有代价的。你不能从后台线程修改用户界面对象。你需要发一条消息,忘记提及这一点。因此,它是有代价的实际上是这样的:BTserial.DataReceived+=(sender,e)=>{Debug.WriteLine(“数据输入!”);//如果(e.EventType==SerialData.Chars){Debug.WriteLine(“Chars!”);检查是否收到了字符;//创建新缓冲区(不知道我是如何使用它们的:))啊,我明白了!它就像一个符咒……只是为了澄清一些事情。
Lambda
意味着你采用了我的datareceived方法并将其放入我的connect中,对吗?不确定你的意思。我明白在connect()方法中运行它的想法。但不明白:
Action Toberunguithread=()=>this.theTextBox.Text=data;this.Invoke(toberunguithread);
…我在
(发送方,e){
(预期为“=>”的
{
上得到语法错误我为我之前犯的错误感到抱歉..再看一看代码..我错误地认为connect方法是Form1类的一部分,它是一个实例方法。然后我意识到它不是该类的一部分,它属于serialConn,并且是静态的。尝试发送表单实例(此)从按钮的click事件处理程序到您的connect方法。我重新编辑了整个帖子。通过ToBerunguithread操作,我的意思是,实际触摸表单和文本框并不是问题的结束。您还需要以非常安全的方式更改Text属性。SerialPort类在b上运行命令后台线程。这样,用户界面将永远不会冻结。用户界面线程需要不受长作业的影响,才能处理鼠标单击之类的操作。但所有这些都是有代价的。你不能从后台线程修改用户界面对象。你需要发一条消息,忘记提及这一点。因此,它是有代价的实际上是:BTserial.DataReceived+=(sender,e)=>{Debug.WriteLine(“数据输入”)