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

时间:2015-08-26 13:11:59

标签: c# winforms serial-port deadlock

在从条形码扫描仪获取一些数据后尝试打开新表单时遇到问题。我们的想法是使用打开的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事件而不是设置Timer(~250ms)并检查ByteToRead属性,但我遇到了同样的问题。

我还会坚持使用Form.Show()的工作版本,但不幸的是我需要将该对话框设置为模态。

如果您对问题可能存在任何疑问,我会非常高兴。 提前谢谢!

2 个答案:

答案 0 :(得分:0)

因为你在Form2中使用你的串口,所以可能是某种死锁。 您能举例说明您在表单中使用serialPort1做什么吗? 你的表格有时冻结的事实也是一个很好的指示。

如果可以,请将必要的数据交给第二个表格。

Form2 frm = new Form2(text);

如果无法做到这一点,您必须检查您的所有方法是否都是线程安全的。 (=> https://en.wikipedia.org/wiki/Thread_safety

答案 1 :(得分:0)

调用show对话框后,最终会出现一个对话框结果。此对话框结果会阻止您在处理之前创建另一个对话框(如here所述)。

您应该手动处理它或将对话框调用放入使用调用

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

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

我认为当不再使用对话框时,GC应该为您执行此操作。但我不确定调用有多好。

修改 一点赌博,但试试这个:

SelectedItem="{Binding SelectedKonto, Mode=TwoWay}"