Question

I have a question concerning why my C# interface is freezing during a serial port connection. If I connect to a serial port that is valid (my device which sends the number of bytes I am expecting) the interface doesn't freeze. However if the user attempts to connect to another port on the computer or the wrong model of my device the program gets no data back when it is send a '?' character and so the first line: message[i] = (byte)port.BaseStream.ReadByte(); causes a timeout and falls into my catch and attempt to connect 3 times then alerts the user of the failed connection. The UI works fine aftet the three attempts are done, but while they are going on the UI is non responsive. Any ideas? Thanks in advance, below is my code.

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)
        {

Above is my code that is run continuously via a DispatcherTimer object set to run every 10 ms.

Was it helpful?

Solution 2

You could use a Thread or you could use Task TPL. There are also some events you can utilize on the SerialPort class such as DataReceived

How about changing it from Read to BeginRead. You you can then use 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?
    }

OTHER TIPS

In order to keep the application responsive, it is advisable to use threads. The communication with serial port is a blocking call and it waits for a timeout before it could determine that the port is not working.

Ideal solution is to use a background worker component and let it make attempt to connect to the serial port.

You can try moving communication through serial port to a separate thread, or set a lower timeout.

DispatcherTimer according to the MSDN is:

A timer that is integrated into the Dispatcher queue which is processed at a specified interval of time and at a specified priority.

Which means that it runs on the same thread where Dispatcher pupms messages. So during the process of your timer request it will stop execution or processing other stuff in queue.

To resolve this use the code that connects to serail port in System.Timers.Timer class events, which run on seprate thread, so will not block UI during their execution.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top