【问题标题】:C# How to pass array of var length to eventhandlerC#如何将var长度数组传递给事件处理程序
【发布时间】:2014-03-27 19:14:45
【问题描述】:

我正在尝试从 C# 中的串行端口读取值。 这是接收到新数据时事件处理程序的代码:

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    int bytes = serialPort1.BytesToRead;
    counter = bytes;
    byte[] comBuffer = new byte[bytes];
    serialPort1.Read(comBuffer, 0, bytes);
    this.Invoke(new EventHandler(DisplayText));

}

这是字节应该写入文本框但现在填充测试代码的地方:

private void DisplayText(object sender, EventArgs e)
{
     counter2 += counter;
     RxString = counter2.ToString();
     textBox1.AppendText(RxString + "\r\n");

}

所以我喜欢 C 编程,但不喜欢 C#,如果有人能告诉我如何将 byte[] 数组放入事件处理程序以处理数据,我将不胜感激。我最大的问题是数组的长度是可变的。

非常感谢!

【问题讨论】:

  • 你为什么打电话给DisplayText作为一个事件?为什么不只是作为一种方法?我不明白你在这里使用的模式。

标签: c# arrays variables eventhandler


【解决方案1】:

解决问题的正确方法是创建一个派生自 EventArgs 的类和一个使用它的事件处理程序。然后您可以在收到数据时引发此事件。

事件处理程序:

public class MyDataReceivedEventArgs : EventArgs
{
    public byte[] Bytes { get; set; }
}

事件:

public event EventHandler<MyDataReceivedEventArgs> DataReceived;
private void OnDataReceived(MyDataReceivedEventArgs e)
{
    if(DataReceived != null) DataReceived(this, e);
}

当收到这样的数据时触发事件:

OnDataReceived(new MyDataReceivedEventArgs { Bytes = comBuffer });

【讨论】:

    【解决方案2】:

    不要使用标准的 EventHandler 签名,而是使用更适合您需要的方法签名:

    private void DisplayText(string stringToDisplay)
    {
         textBox1.AppendText(stringToDisplay + "\r\n");
    }
    

    在您的事件处理程序中,将字节数组转换为字符串并将其传递给您的 DisplayText 方法:

    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        int bytes = serialPort1.BytesToRead;
        counter = bytes;
        byte[] comBuffer = new byte[bytes];
        serialPort1.Read(comBuffer, 0, bytes);
    
        // convert byte array to string
        string stringToShow = Encoding.ASCII.GetString(bytes);
        this.Invoke(() => DisplayText(stringToShow));
    }
    

    注意:如果您的数据包含 8 位字符(超出 ASCII 范围),请使用适当的编码将其转换为字符串。

    【讨论】:

    • 基本上就是这个,虽然我还是不知道你为什么要用Invoke
    • @Yuck:DataReceived 可能发生在后台线程中,因此 Invoke 会确保文本框在 UI 线程中更新。
    【解决方案3】:

    使用除EventHandler 之外的其他内容。 EventHandler 只需要 senderEventArgs 所以你需要不同的委托类型。我会使用类似的东西:

    private void DisplayText(object sender, DataEventArgs e)
    {
         //e.Data is now available
    
         counter2 += counter;
         RxString = counter2.ToString();
         textBox1.AppendText(RxString + "\r\n");
    }
    
    public class DataEventArgs : EventAgrs
    {
        public byte[] Data {get; set;}
    }
    

    然后调用它使用

    byte[] comBuffer = new byte[bytes];
    serialPort1.Read(comBuffer, 0, bytes);
    this.Invoke(new EventHandler<DataEventArgs>(DisplayText)
              , new DataEventArgs {Data = comBuffer});
    

    【讨论】:

    • 谢谢,这正是我需要的!但是当试图在我的代码中实现这一点时,DisplayText,new DataEventArgs {Data = comBuffer} 会显示方法名
    • @user3470049 错字 - 已修复。
    • 不幸的是我很烦人,但问题是一样的:(
    • @user3470049 修正了括号。
    • e.Data有什么特别的技巧吗?只是尝试像字节数组一样访问它,但测试像'counter = e.Data.Length;'这样的东西不起作用,因为“System.eventArgs”不包含“数据”的定义:(
    猜你喜欢
    • 2011-05-02
    • 1970-01-01
    • 2018-10-24
    • 1970-01-01
    • 2012-08-30
    • 2018-12-05
    • 1970-01-01
    相关资源
    最近更新 更多