在c#windows窗体应用程序中使用showDialog()方法打开窗体后未触发串行端口事件
事实上,当人们/顾客打电话到餐厅点菜时,我正在从com串口接收数据以获取电话/手机号码 第一次串行端口完全监听,然后windows窗体正确显示电话号码。要打开windows窗体,我必须使用this.showdialog()而不是this.show()。因为在当前表单后面已经打开了几个表单 问题发生在第一次显示对话框、串口未接听电话或串口功能触发后,并且表单未使用新的呼叫者电话号码更新 我知道这是因为使用了showdialog(),但我必须使用它。我记下了我用过的密码在c#windows窗体应用程序中使用showDialog()方法打开窗体后未触发串行端口事件,c#,winforms,serial-port,showdialog,C#,Winforms,Serial Port,Showdialog,事实上,当人们/顾客打电话到餐厅点菜时,我正在从com串口接收数据以获取电话/手机号码 第一次串行端口完全监听,然后windows窗体正确显示电话号码。要打开windows窗体,我必须使用this.showdialog()而不是this.show()。因为在当前表单后面已经打开了几个表单 问题发生在第一次显示对话框、串口未接听电话或串口功能触发后,并且表单未使用新的呼叫者电话号码更新 我知道这是因为使用了showdialog(),但我必须使用它。我记下了我用过的密码 private void
private void FindCom()
{
尝试
{
//show(“称为Find Com”);
WriteLogFile(“文件:调用者”、“方法:FindCom”、“--FindCom调用--”);
字符串COM=RunProcess(“FindCOMET.exe”);//使用自动查找查找单元的
string[]COMPorts=COM.Split(“;”);//将自动查找字符串拆分为各个端口
COM=COMPorts[0];//选择第一个COM端口
//使用所有设置初始化COM端口。
serialPort=新的serialPort();
serialPort.PortName=COM;
serialPort.BaudRate=1200;
serialPort.DataBits=8;
serialPort.StopBits=停止位.1;
serialPort.Parity=奇偶校验.None;
serialPort.DataReceived+=新的SerialDataReceiveDevenHandler(this.serialPort\u DataReceived);
serialPort.ReadTimeout=100;//数据包结束超时通知需要
serialPort.Open();
}
捕获(例外情况除外)
{
//Show(“Exception1”+ex.Message.ToString());
LogFile.WriteLogFile(“文件:调用者”,“方法:FindCom”,“EM:+ex.Message.ToString());
}
//循环,直到用户按下一个键,然后退出
//System.Console.WriteLine(“按任意键退出”);
//Console.ReadKey();
}
//用于读取数据的变量
int[]缓冲区=新int[255];
int指针;
private void serialPort_DataReceived(对象发送方,System.IO.Ports.SerialDataReceivedEventArgs e)
{
尝试
{
//将所有当前缓冲区读入数组
for(int c=0;c!=serialPort.BytesToRead;c++)
{
缓冲区[指针]=serialPort.ReadByte();
指针++;
}
}
捕获(TimeoutException x)
{
尝试
{
COMET_数据cid=新COMET_数据(缓冲区);
//在这里输出数据或调用程序中的某些内容
字符串mobileNo=cid.getCIDNumber();
字符串电话=string.Empty;
var getName=string.Empty;
if(mobileNo!=null)
{
mobileNo=Regex.Replace(mobileNo,[^0-9]+”,string.Empty);
//MessageBox.Show(“FullNumber”+mobileNo);
if(mobileNo[0]=“9”)
{
mobileNo=mobileNo.子串(1);
}
//MessageBox.Show(mobileNo.Substring(0,2)+“OF=>”+mobileNo);
如果(移动子串(0,2)=“07”)
{
//mobileNo=mobileNo;
Text=mobileNo;
lblMobileNo.Text=mobileNo;
}
其他的
{
电话=移动电话;
//MessageBox.Show(“电话:+电话”);
Text=电话;
lblMobileNo.Text=电话;
}
getName=cid.getCIDName();
}
其他的
{
lblCustomerName.Text=“不可用”;
txtbxMobileNo.Text=“保留”;
lblMobileNo.Text=“保留”;
}
//MessageBox.Show(mobileNo);
SaveCommetCaller(mobileNo);
//重置缓冲区指针和缓冲区
缓冲区=新整数[255];
指针=0;
//对于(int i=1;i>=0;i--)
isFormOpen=true;
this.ShowDialog();
serialPort.DiscardInBuffer();
//is_open=false;
}
捕获(例外情况除外)
{
LogFile.WriteLogFile(“文件:调用者”,“方法:DataReceived”,“EM:+ex.Message.ToString());
}
//serialPort.DataReceived+=新的SerialDataReceiveDevenHandler(this.serialPort\u DataReceived);
}
最后
{
//serialPort.DataReceived+=serialPort_DataReceived;
}
}
无论发生什么情况,ShowDialog()都会阻止您的应用程序。
我能取得的最好成绩可以在这里看到:
首先,将事件发射器放在单独的线程/任务中,并将事件发射器注入第一个窗体:
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var callReceiver = new CallReceiver();
var thread = new Thread(callReceiver.WaitForCall);
thread.Start();
Application.Run(new Form1(callReceiver));
}
}
public class CallReceiver
{
public event EventHandler<int> CallReceived;
public void WaitForCall()
{
var i = 0;
while (true)
{
Thread.Sleep(1000);
OnCallReceived(i++);//Dummy event emitter
}
}
protected virtual void OnCallReceived(int e)
{
CallReceived?.Invoke(this, e);
}
}
调用this.invokeIfrequeired()是为了避免跨线程问题,如下所示:
static class Invoker
{
public static void InvokeIfRequired(this Control control, MethodInvoker action)
{
if (control.InvokeRequired)
{
control.Invoke(action);
}
else
{
action();
}
}
}
DisplayCallForm.cs:
public partial class DisplayCallForm : Form
{
private readonly CallReceiver _callReceiver;
public DisplayCallForm(CallReceiver callReceiver)
{
InitializeComponent();
_callReceiver = callReceiver;
_callReceiver.CallReceived += CallReceiverOnCallReceived;
}
private void CallReceiverOnCallReceived(object sender, int i)
{
this.InvokeIfRequired(() =>
{
label1.Text = i.ToString();
});
}
}
呵呵
public partial class DisplayCallForm : Form
{
private readonly CallReceiver _callReceiver;
public DisplayCallForm(CallReceiver callReceiver)
{
InitializeComponent();
_callReceiver = callReceiver;
_callReceiver.CallReceived += CallReceiverOnCallReceived;
}
private void CallReceiverOnCallReceived(object sender, int i)
{
this.InvokeIfRequired(() =>
{
label1.Text = i.ToString();
});
}
}
private void button1_Click(object sender, EventArgs e)
{
serialPort1.Close(); // <---
Form1 nextForm = new Form1();
Hide();
nextForm.ShowDialog();
Close();
}