串口尝试连接时C#UI冻结
我有一个问题,为什么我的C#接口在串行端口连接期间冻结。如果我连接到一个有效的串行端口(我的设备发送我期望的字节数),接口不会冻结。但是,如果用户试图连接到计算机上的另一个端口或我的设备的错误型号,则程序在发送“?”字符时不会返回任何数据,因此第一行是:message[i]=(byte)port.BaseStream.ReadByte();导致超时并落入我的陷阱,尝试连接3次,然后向用户发出连接失败的警报。在三次尝试完成后,UI工作正常,但当它们进行时,UI没有响应。有什么想法吗?提前谢谢,下面是我的代码串口尝试连接时C#UI冻结,c#,wpf,dispatchertimer,C#,Wpf,Dispatchertimer,我有一个问题,为什么我的C#接口在串行端口连接期间冻结。如果我连接到一个有效的串行端口(我的设备发送我期望的字节数),接口不会冻结。但是,如果用户试图连接到计算机上的另一个端口或我的设备的错误型号,则程序在发送“?”字符时不会返回任何数据,因此第一行是:message[i]=(byte)port.BaseStream.ReadByte();导致超时并落入我的陷阱,尝试连接3次,然后向用户发出连接失败的警报。在三次尝试完成后,UI工作正常,但当它们进行时,UI没有响应。有什么想法吗?提前谢谢,下面
public void windowLoop(object sender, EventArgs e)
{
if (Global.connecting)
{
try
{
if (i == 0) { port.BaseStream.Flush(); port.BaseStream.WriteByte(63); }
message[i] = (byte)port.BaseStream.ReadByte();
if (i == 6)
{
connectAttempts = 1;
i = 0;
String result = Encoding.ASCII.GetString(message);
if (result == "ASUTTON")
{
//connection succeeded
Global.connecting = false;
Global.receiving = true;
setDisplay(2);
}
else
{
//connection failed
Global.connecting = false;
disconnect();
MessageBox.Show(radio, "You are not connection to an Agent (Radio Version)", "Connection Failed", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
else
{
i++;
}
}
catch
{
if (connectAttempts >= connectAttemptsLimit)
{
connectAttempts = 1;
Global.connecting = false;
disconnect();
MessageBox.Show(radio, "Your device failed to connect to the program.", "Connection Failed", MessageBoxButton.OK, MessageBoxImage.Information);
}
else
{
connectAttempts++;
}
}
}
else if (Global.sending)
{
上面是我的代码,它通过设置为每10毫秒运行一次的Dispatchermer对象连续运行。为了保持应用程序的响应性,建议使用线程。与串行端口的通信是一个阻塞调用,它会等待超时,然后才能确定端口是否工作
理想的解决方案是使用后台工作程序组件,让它尝试连接到串行端口。为了保持应用程序的响应性,建议使用线程。与串行端口的通信是一个阻塞调用,它会等待超时,然后才能确定端口是否工作
理想的解决方案是使用后台工作程序组件,让它尝试连接到串行端口。您可以尝试通过串行端口将通信移动到单独的线程,或设置较低的超时。您可以尝试通过串行端口将通信移动到单独的线程,或者设置较低的超时时间。根据MSDN是: 集成到调度程序队列中的计时器 以指定的时间间隔和指定的优先级处理 这意味着它运行在调度程序处理消息的同一线程上。所以,在计时器请求的过程中,它将停止执行或处理队列中的其他内容 要解决此问题,请使用连接到类事件中serail端口的代码,该类事件在seprate线程上运行,因此在执行过程中不会阻止
UI
。根据MSDN is:
集成到调度程序队列中的计时器
以指定的时间间隔和指定的优先级处理
这意味着它运行在调度程序处理消息的同一线程上。所以,在计时器请求的过程中,它将停止执行或处理队列中的其他内容
要解决此问题,请使用连接到类事件中serail端口的代码,该类事件在seprate线程上运行,因此在执行过程中不会阻止
UI
。可以使用线程,也可以使用TPL。还可以在SerialPort类上使用一些事件,例如
将其从Read
更改为。然后可以使用AsyncCallback
byte[] received = new byte[port.BytesToRead];
result = port.BaseStream.BeginRead(received
, 0, port.BytesToRead, new AsyncCallback(ReadCallBack), port.BaseStream);
private void ReadCallBack(IAsyncResult ar)
{
Stream stream = (Stream)ar.AsyncState;
// Do reading here?
}
您可以使用线程
,也可以使用TPL。还可以在SerialPort类上使用一些事件,例如
将其从Read
更改为。然后可以使用AsyncCallback
byte[] received = new byte[port.BytesToRead];
result = port.BaseStream.BeginRead(received
, 0, port.BytesToRead, new AsyncCallback(ReadCallBack), port.BaseStream);
private void ReadCallBack(IAsyncResult ar)
{
Stream stream = (Stream)ar.AsyncState;
// Do reading here?
}