从serialPort获取数据后打开新表单

本文关键字:新表单 表单 serialPort 获取 数据 | 更新日期: 2023-09-27 18:09:51

我遇到了一个问题,而试图从条形码扫描器获得一些数据后打开新的形式。我们的想法是使用一个打开serialPort的Main表单,并使用DataReceived事件读取数据。当这个时刻发生时,我想打开新表单并将数据传递给它。(理想的状态是传递serialPort,这样它也会在那里起作用)

    private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
    {
        string barcode = serialPort1.ReadExisting();
        if (this.InvokeRequired)
        {
            this.Invoke(new SetCallBack(SetText), new object[] { barcode });
        }
    }
    delegate void SetCallBack(string text);
    private void SetText(string text)
    {
            Form2 frm = new Form2(text, serialPort1);
            frm.ShowDialog();
            serialPort1.DiscardInBuffer();
    }

它工作一次或两次,但之后的控制冻结。当我将代码改为

frm.Show();

它工作没有问题(或者至少它们不可见)。我得到一些死锁那里,因为。showdialog ()?

//注意,我还从数据库中获取了一些数据,这里没有显示,但它也可能导致问题

有人建议我不要使用DataReceive事件,而不是设置定时器(~250ms)并检查ByteToRead属性,但我遇到了同样的问题。

我也会坚持使用Form.Show()的工作版本,但不幸的是,我需要这个对话框是模态的。

如果你有任何想法的问题可能在哪里,我将非常高兴。提前感谢!

从serialPort获取数据后打开新表单

调用show对话框后,您将得到一个对话框结果。此对话框结果阻止您创建另一个对话框,直到您处置它(如这里所述)。

您应该手动释放它或将对话框调用放在using调用

    private void SetText(string text)
        {
                using (Form2 frm = new Form2(text, serialPort1))
                {
                        frm.ShowDialog();
                }
                serialPort1.DiscardInBuffer();
        }

private void SetText(string text)
    {
            Form2 frm = new Form2(text, serialPort1);
            frm.ShowDialog();
            frm.Dispose();
            serialPort1.DiscardInBuffer();
    }

我认为GC应该在对话框不再使用时为您做这件事。但我不确定这对调用有多好。

编辑有点冒险,但是试试这个:

private object mScanLock = new object();
private void SetText(string text)
        {
           lock(mScanLock) {
                Form2 frm = new Form2(text, serialPort1);
                frm.ShowDialog();
                frm.Dispose();
                serialPort1.DiscardInBuffer();
              }
        }

可能是某种死锁,因为您在Form2中使用了串行端口。你能给一个例子你是如何处理你表单中的serialPort1的吗?事实上,你的表单有时冻结也是一个很好的指示。

如果可能的话,请将必要的数据提交到您的第二张表格中。

Form2 frm = new Form2(text);

如果这是不可能的,你必须检查是否真的所有的方法都是线程安全的。(=> https://en.wikipedia.org/wiki/Thread_safety)