0

我有一个关于为什么我的 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 对象连续运行。

4

4 回答 4

2

为了保持应用程序的响应,建议使用线程。与串行端口的通信是一个阻塞调用,它会在确定端口不工作之前等待超时。

理想的解决方案是使用后台工作组件并让它尝试连接到串行端口。

于 2013-03-26T11:28:45.547 回答
1

您可以使用 aThread或使用TaskTPL。您还可以在 SerialPort 类上使用一些事件,例如DataReceived

如何将其从 更改ReadBeginRead。然后你就可以使用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?
    }
于 2013-03-26T11:41:10.410 回答
1

您可以尝试将通过串行端口的通信移动到单独的线程,或设置较低的超时时间。

于 2013-03-26T11:28:47.447 回答
1

根据 MSDN 的DispatcherTimer是:

一个集成到 Dispatcher 队列中的计时器,它以指定的时间间隔和指定的优先级进行处理。

这意味着它在 Dispatcher pupms 消息所在的同一线程上运行。因此,在您的计时器请求过程中,它将停止执行或处理队列中的其他内容。

要解决此问题,请使用System.Timers.Timer类事件中连接到 serail 端口的代码,这些事件在单独的线程上运行,因此UI在执行期间不会阻塞。

于 2013-03-26T11:29:52.143 回答