我有一个问题,关于为什么我的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毫秒运行一次的DispatcherTimer对象连续运行。
答案 0 :(得分:2)
为了使应用程序保持响应,建议使用线程。与串行端口的通信是一个阻塞调用,它等待超时才能确定端口不工作。
理想的解决方案是使用后台工作程序组件,并尝试连接到串行端口。
答案 1 :(得分:1)
您可以尝试通过串口将通信移动到单独的线程,或设置较低的超时。
答案 2 :(得分:1)
集成到Dispatcher队列中的计时器 在指定的时间间隔和指定的优先级处理。
这意味着它在Dispatcher pupms消息的同一个线程上运行。因此,在您的计时器请求过程中,它将停止执行或处理队列中的其他内容。
要解决此问题,请使用在System.Timers.Timer类事件中连接到serail端口的代码,该事件在单独的线程上运行,因此在执行期间不会阻塞UI
。
答案 3 :(得分:1)
您可以使用Thread
,也可以使用Task
TPL。您还可以在SerialPort类上使用一些事件,例如DataReceived
如何将其从Read
更改为BeginRead
。然后,您可以使用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?
}