For the purposes of this question I'm including a class of mine in its entirety:
public class SerialPortConnection
{
private SerialPort serialPort;
private string ping;
double failOut;
bool isReceiving;
public SerialPortConnection(string comPort = "Com1", int baud = 9600, System.IO.Ports.Parity parity = System.IO.Ports.Parity.None, int dataBits = 8, System.IO.Ports.StopBits stopBits = System.IO.Ports.StopBits.One, string ping = "*IDN?", double failOut = 2)
{
this.ping = ping;
this.failOut = failOut * 1000;
try
{
serialPort = new SerialPort(comPort, baud, parity, dataBits, stopBits);
}
catch (Exception e)
{
throw e;
}
}
//Open Serial Connection. Returns False If Unable To Open.
public bool OpenSerialConnection()
{
//Opens Initial Connection:
try
{
serialPort.Open();
serialPort.Write("REMOTE\r");
}
catch (Exception e)
{
throw e;
}
serialPort.Write(ping + "\r");
var testReceived = "";
isReceiving = true;
Timer StopWatch = new Timer(failOut);
StopWatch.Elapsed += new ElapsedEventHandler(OnTimedEvent);
StopWatch.Interval = failOut;
StopWatch.Enabled = true;
while (isReceiving == true)
{
try
{
testReceived += serialPort.ReadExisting();
}
catch (Exception e)
{
throw e;
}
}
StopWatch.Dispose();
if (testReceived.Contains('>'))
{
return true;
}
else
{
return false;
}
}
public string WriteSerialConnection(string SerialCommand)
{
try
{
serialPort.Write(String.Format(SerialCommand + "\r"));
var received = "";
bool isReceiving = true;
Timer StopWatch = new Timer(failOut);
StopWatch.Elapsed += new ElapsedEventHandler(OnTimedEvent);
StopWatch.Interval = failOut;
StopWatch.Enabled = true;
while (isReceiving == true)
{
try
{
received += serialPort.ReadExisting();
}
catch (Exception e)
{
throw e;
}
}
if (received.Contains('>'))
{
return received;
}
else
{
received = "Error: No Data Received From Device";
return received;
}
StopWatch.Dispose();
}
catch (Exception e)
{
throw e;
}
}
//Closes Serial Connection. Returns False If Unable To Close.
public bool CloseSerialConnection()
{
try
{
serialPort.Write("LOCAL\r");
serialPort.Close();
return true;
}
catch (Exception e)
{
throw e;
}
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
isReceiving = false;
}
}
What I'm attempting to do here is keep a loop running for a set amount of time (two seconds in this case) because the device connected to the serial port I'm working with is unpredictable. I don't know what data I will receive from it and I don't know how long it will take. That can't be fixed and is something I have to work with. My best option, currently, is to wait a set amount of time and check the data I've received for an end token (">"). I've tried wiring up a timer even in the class like so:
Timer StopWatch = new Timer(failOut * 1000);
StopWatch.Elapsed += new ElapsedEventHandler(OnTimedEvent);
StopWatch.Interval = failOut;
StopWatch.Enabled = true;
But it doesn't appear to work. The event itself looks like so:
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
isReceiving = false;
}
My objective is to cut the loop isReceiving is tied to:
(while isReceiving == true)
{
//Do Something
}
But it doesn't appear to work. I assume I've completely misunderstood the function of the timer but I've had suggestions before to implement it. What am I doing wrong? If I'm just completely misusing it, what can I use instead of a timer? As I've said, I've no choice but to wait a set amount of time and check what I've received. That can't be avoided or handled in any way other than waiting and hoping I get something.
EDIT:
Maybe it's best I clarify this. The OnTimedEvent event is firing and the variable is set to false but it doesn't cut the loop as isReceiving
isn't getting set to false.
EDIT 2:
Mr. Passant's answer works beautifully barring a strange error I'm encountering. As I don't believe it's a problem within his answer, it's more likely that it's a hardware flaw, or something else strange and obscure along those lines, I'm leaving his answer marked as accepted. I recommend anyone that chooses to implement his answer also view the question I have submitted here:
Apparent IO.Ports.SerialPort Flaw in C# or Possible Hardware Flaw
You are making it too difficult on yourself. Simply change the SerialPort.NewLine property to ">". And use SerialPort.ReadLine() to read the response. You can still use a timeout if you need it, assign the SerialPort.ReadTimeout property and be prepared to catch the TimeoutException.