在c#中从组合框中添加/删除COM端口

本文关键字:删除 COM 添加 端口 组合 | 更新日期: 2023-09-27 18:01:37

我正在尝试编写一个程序,该程序利用ComboBox来显示从以下方法获得的当前连接的COM端口:

System.IO.Ports.SerialPort.GetPortNames()
这个想法是初始化一个线程,每秒检查当前可用的COM端口,并相应地更新ComboBox。尽管我尽了最大的努力,我还是不能使它工作。

更新ComboBox内容的代码如下:

    private void Form1_Load(object sender, EventArgs e)
    {
        availPorts = new BindingList<String>();
        Thread t = new Thread(new ThreadStart(update));
        t.Start();
    }
    private void update()
    {
        this.comboBox1.DataSource = availPorts;
        while (true)
        {
            Console.WriteLine("CHECK");
            foreach (String port in System.IO.Ports.SerialPort.GetPortNames())
            {
                if (!availPorts.Contains(port))
                {
                    Console.WriteLine("FOUND");
                    availPorts.Add(port);
                }
            }
            Thread.Sleep(1000);
        }
    }

当找到端口时,我可以看到控制台消息,但是ComboBox仍然为空。

在c#中从组合框中添加/删除COM端口

试着这样修改代码。

BindingList<String> availPorts = new BindingList<String>();
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
private void Form1_Load(object sender, EventArgs e)
{
    Thread t = new Thread(new ThreadStart(update));
    t.Start();
    autoResetEvent.WaitOne();
    this.comboBox1.DataSource = availPorts;
}
private void update()
{
    //this.comboBox1.DataSource = availPorts;
    while (true)
    {
        Console.WriteLine("CHECK");
        foreach (String port in System.IO.Ports.SerialPort.GetPortNames())
        {
            if (!availPorts.Contains(port))
            {
                Console.WriteLine("FOUND");
                availPorts.Add(port);
            }
        }
        autoResetEvent.Set();
    }
}

ComboBox没有被更新,因为为运行update方法而创建的线程正在尝试更新属于另一个线程的可视控件。在大多数情况下,这会抛出一个错误,但是在这里不会。

我通过首先创建一个方法来解决这个问题,与update分开,该方法只处理向数据源添加COM端口名称。在这个方法中有一个if语句检查是否需要调用:

private void addPort(String port)
    {
        if (this.InvokeRequired)
        {
            this.Invoke(new addPortDelegate(addPort), port);
        }
        else
        {
            availablePorts.Add(port);
            Console.WriteLine("FOUND");
        }
    }

如果需要调用,则通过委托在正确的线程内调用该方法:

private delegate void addPortDelegate(String s);

这将导致在连续执行更新方法检测到新的COM端口时更新ComboBox。可以编写一个类似的方法来删除已与系统断开连接的COM端口。但是不要忘记在窗体关闭时结束线程,否则它将无限旋转。