У меня есть программа, которая читает с последовательного порта в C #.Мне нужно быстро написать в порт, прочитать с него, а затем закрыть его.я не могу оставить это открытым.Я понимаю, что последовательные порты читаются и пишутся медленно, я попытался установить высокие свойства ReadTimeout и WriteTimeout и добавил нить. Сплю, чтобы попытаться утащить время чтения и записи для устройств.Вот немного кода:
мой метод записи в порт:
private void CheckPorts(string testMessage)
{
foreach (string s in SerialPort.GetPortNames())
{
portNumber = Int32.Parse(s.Remove(0, 3));
testSerial = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
if (testSerial.IsOpen)
{
testSerial.Close();
}
testSerial.ReadTimeout = 2000;
testSerial.WriteTimeout = 1000;
testSerial.Open();
if (testSerial.IsOpen)
{
string received;
testSerial.DiscardInBuffer();
try
{
//testSerial.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived);
testSerial.Write(testMessage);
System.Threading.Thread.Sleep(2000);
received = testSerial.ReadExisting(); //EITHER I USE THIS OR EVENT HANDLER, NOT BOTH
}
catch (TimeoutException e)
{
testSerial.Close();
continue;
}
if (received.Length > 0)
{
MessageReceived(received);
}
testSerial.Close();
}
}
}
private void testSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string received = testSerial.ReadExisting();
int y = received.IndexOf("\r");
while (y == -1)
{
received = received + testSerial.ReadExisting();
y = received.IndexOf("\r");
}
if (testSerial.IsOpen)
{
testSerial.Close();
}
}
Мне интересно, если мне абсолютно необходимо использовать обработчик данных, как мне сохранить последовательный порт открытымдостаточно долго, чтобы прочитать из него, но закрыть последовательный порт, прежде чем нужно будет открыть следующий порт?
видите, первый метод вызывается несколько раз, и он повторяет цикл foreach, пытаясь получить сообщение нанесколько портов, а затем пытается прочитать ответ.Итак, в какой-то момент мне нужно закрыть порты, или в следующий раз, когда он проходит через него, он не работает должным образом, потому что порт все еще открыт
ЗДЕСЬ МОЙ ОБНОВЛЕННЫЙ КОД (все еще не работает):
private void CheckPorts(string testMessage, int baudRate)
{
foreach (string s in SerialPort.GetPortNames())
{
var interval = 3000; // ms
var timer = new System.Timers.Timer(interval);
timer.Elapsed += (o, e) =>
{
timer.Enabled = false;
if (testSerial.IsOpen)
testSerial.Close(); // may not be necessary with Dispose?
testSerial.Dispose();
timer.Dispose();
};
portNumber = Int32.Parse(s.Remove(0, 3));
testSerial = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
testSerial.ReadTimeout = 2000;
testSerial.WriteTimeout = 2000;
if (testSerial.IsOpen)
{
testSerial.Close();
}
testSerial.Open();
timer.Enabled = true;
if (testSerial.IsOpen)
{
string received;
//testSerial.DiscardInBuffer();
//autoEvent = new AutoResetEvent(false);
try
{
// testSerial.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived);
// autoEvent.Reset();
lblPortNum.Content = s;
lblPortNum.Refresh();
testSerial.Write(testMessage);
//System.Threading.Thread.Sleep(2000);
//testSerial.NewLine = "\r\n";
byte[] rBuff = new byte[2];
int rCnt = testSerial.Read(rBuff, 0, 2);
System.Text.Encoding enc = System.Text.Encoding.ASCII;
received = enc.GetString(rBuff);
//received = testSerial.ReadLine();
}
catch (TimeoutException e)
{
testSerial.Close();
continue;
}
if (received.Length > 0)
{
MessageReceived(received, Int16.Parse(s.Remove(0, 3)));
}
/*
if (autoEvent.WaitOne(2000))
{
// the port responded
// testSerial.Close();
autoEvent.Dispose();
lblPortNum.Content = "HEY I RESPONDED";
}
else
{
testSerial.Close();
autoEvent.Dispose();
continue;
// port did not respond within 2 seconds
}*/
//testSerial.Close();
}
}
}
ВНОВЬ ОБНОВЛЕНО (все еще не работает должным образом)
private void CheckPorts(string testMessage, int baudRate)
{
foreach (string s in SerialPort.GetPortNames())
{
portNumber = Int32.Parse(s.Remove(0, 3));
// MUST BE LOCAL
var serialOneOfMany = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
serialOneOfMany.ReadTimeout = 2000;
serialOneOfMany.WriteTimeout = 2000;
if (serialOneOfMany.IsOpen)
{
serialOneOfMany.Close();
}
// timer must be defined _after_ serialOneOfMany
var interval = 3000; // ms
var timer = new System.Timers.Timer(interval);
timer.Elapsed += (o, e) =>
{
timer.Enabled = false;
if (serialOneOfMany.IsOpen)
serialOneOfMany.Close(); // may not be necessary with Dispose?
serialOneOfMany.Dispose();
timer.Dispose();
};
if (serialOneOfMany.IsOpen)
{
string received;
try
{
lblPortNum.Content = s;
lblPortNum.Refresh();
serialOneOfMany.Write(testMessage);
byte[] rBuff = new byte[2];
int rCnt = serialOneOfMany.Read(rBuff, 0, 2);
System.Text.Encoding enc = System.Text.Encoding.ASCII;
received = enc.GetString(rBuff);
}
catch (TimeoutException e)
{
serialOneOfMany.Close();
continue;
}
if (received.Length > 0)
{
CheckIfTheMessageMatches(received, Int16.Parse(s.Remove(0, 3)));
}
}
}
}
так что с этим обновлением, он просто проходит через код, я могу шаг за шагом проходить код, но этоне останавливается на 3 секунды вообще.если я запускаю его без каких-либо перерывов в отладке, он просто проходит через это в течение доли секунды
ОБНОВЛЕНИЕ 10-25-11
private void CheckPorts(string testMessage, int baudRate)
{
foreach (string s in SerialPort.GetPortNames())
{
string received = "";
testSerial = new SerialPort(s,baudRate, Parity.None, 8, StopBits.One);
lblStatus.Content = "Scanning...";
lblStatus.Refresh();
if (testSerial.IsOpen)
{
testSerial.Close();
}
else
{
testSerial.Open();
}
if (testSerial.IsOpen)
{
try
{
testSerial.NewLine = "\r";
lblPortNum.Content = s;
lblPortNum.Refresh();
testSerial.WriteTimeout= 500;
testSerial.ReadTimeout = 1000;
testSerial.WriteLine(testMessage);
System.Threading.Thread.Sleep(500);
/*THIS DOESN'T WORK
byte[] buffer = new byte[testSerial.BytesToRead];
int rCnt = testSerial.Read(buffer, 0, buffer.Length);
received = enc.GetString(buffer);*/
//received = Convert.ToString(testSerial.BaseStream.Read(buffer, 0, (int)buffer.Length));
received = testSerial.ReadLine();
int y = received.IndexOf("\r");
while (y == -1)
{
received = received + testSerial.ReadExisting();
y = received.Length;
}
if (lblInfo.Dispatcher.Thread == Thread.CurrentThread)
{
CheckIfTheMessageMatches(received, s);
received = received + lblInfo.Content;
lblInfo.Content = received;
}
else
{
lblInfo.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadCheck(threadCheck), received);
}
if (testSerial.IsOpen)
{
testSerial.Close();
}
/*I USE THIS WITH THE sPort.Read() METHOD
while (rCnt > 0)
{
if (lblInfo.Dispatcher.Thread == Thread.CurrentThread)
{
CheckIfTheMessageMatches(received, s);
rCnt = 0;
received = received + lblInfo.Content;
lblInfo.Content = received;
}
else
{
lblInfo.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadCheck(threadCheck), received);
}
}
*/
if (testSerial.IsOpen)
{
testSerial.Close();
}
}
catch (TimeoutException e)
{
testSerial.Close();
continue;
}
received = null;
}
}
lblStatus.Content = "Finished Scanning.";
lblPortNum.Content = "";
}
ОБНОВЛЕННЫЙ КОД Вот некоторый новый код, все еще не работающий, dataeventhandler даже не вызывал ни разу.я знаю, что он получает сообщения, потому что у меня есть другая программа, которая работает с последовательными устройствами
private void CheckPorts(string testMessage, int baudRate)
{
foreach (string s in SerialPort.GetPortNames())
{
var serialOneOfMany = new SerialPort(s, baudRate, Parity.None, 8, StopBits.One);
serialOneOfMany.ReadTimeout = 700;
serialOneOfMany.WriteTimeout = 100;
var interval = 500; // ms
var timer = new System.Timers.Timer(interval);
timer.Elapsed += (o, e) =>
{
timer.Enabled = false;
if (serialOneOfMany.IsOpen)
serialOneOfMany.Close(); // may not be necessary with Dispose?
serialOneOfMany.Dispose();
timer.Dispose();
};
timer.Enabled = true;
lblStatus.Content = "Scanning...";
lblStatus.Refresh();
if (serialOneOfMany.IsOpen)
{
serialOneOfMany.Close();
}
else
{
serialOneOfMany.Open();
}
if (serialOneOfMany.IsOpen)
{
string received;
try
{
lblPortNum.Content = s;
lblPortNum.Refresh();
serialOneOfMany.WriteLine(testMessage);
System.Threading.Thread.Sleep(400);
serialOneOfMany.DataReceived += new SerialDataReceivedEventHandler(testSerialPort_DataReceived);
}
catch (TimeoutException e)
{
serialOneOfMany.Close();
continue;
}
}
}
lblStatus.Content = "Finished Scanning.";
lblPortNum.Content = "";
}
private void testSerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort receivingSerial = sender as SerialPort;
string received = receivingSerial.ReadExisting();
int y = received.IndexOf("\r");
while (y == -1)
{
received = received + receivingSerial.ReadExisting();
y = received.IndexOf("\r");
}
if (lblInfo.Dispatcher.Thread == Thread.CurrentThread)
{
string name = receivingSerial.PortName;
received = received + lblInfo.Content;
lblInfo.Content = received;
CheckIfTheMessageMatches(received, name);
}
else
{
lblInfo.Dispatcher.Invoke(DispatcherPriority.Normal, new ThreadCheck(threadCheck), received);
}
if (receivingSerial.IsOpen)
{
receivingSerial.Close();
}
}