У меня есть приложение, которое запрашивает ответ от 3 виртуальных последовательных портов с использованием serialport.datareceived. Это может привести к накоплению потоков. Каждый последовательный порт работает в своем собственном потоке. Через много часов количество потоков, мой рост на 20 000+. Закрытие приложения возвращает потоки. < /P>
private void Init()
{
//...
// do this for each set of scales
serialPort.DataReceived -= SerialDataReceivedHandler;
serialPort.DataReceived += SerialDataReceivedHandler;
ThreadPool.QueueUserWorkItem(a => BeginWeighing(scales));
//..
}
< /code>
private void BeginWeighing(Scales scales)
{
//....
// Request data from serial port device
serialPort.Write((isC320 ? C300_READ_GROSS : R300_READ_GROSS) + sgCRLF);
//....
}
< /code>
Here is the event handler. I don't know the exact length of the incoming response (there are several options). I wait 50ms on that thread before reading the full message (I suspect this is the issue).
private void SerialDataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
// Give the sensor a chance to compose all the data after the first bytes are sent.
// This looks wrong, but I don't know any other way to reliably fetch all the data
// from the existing response.
System.Threading.Thread.Sleep(50);
try
{
SerialPort sp = (SerialPort)sender;
if (sp == null || !sp.IsOpen)
{
Debug.WriteLine("[ERROR] Serial port is null or closed");
return;
}
string sensorData = sp.ReadExisting();
Scales? scales = GetScalesFromSerialPort(sp);
if (scales != null)
{
if (string.IsNullOrEmpty(sensorData))
{
Debug.WriteLine("[ERROR] No data in serialport scales event on race " + scales.raceNumber);
}
else
{
int dataLen = sensorData.Length;
bool isC320 = scales.isC320;
// Received gross weight data
if (dataLen >= 17 && sensorData.StartsWith(isC320 ? Scales.C300_RECEIVED_GROSS : Scales.R300_RECEIVED_GROSS))
{
string hexWeight = sensorData.Substring(9, 8);
if (int.TryParse(hexWeight, System.Globalization.NumberStyles.HexNumber, null, out int weightInt))
{
// Div by 10 for 1 decimal place on R320 scales.
UpdateWeight(scales.raceNumber, (double)weightInt / 10d);
}
else
{
Debug.WriteLine("Scales (" + scales.raceNumber + ") weight data: (invalid)");
}
}
else if (dataLen >= 15 && sensorData.StartsWith(isC320 ? Scales.C300_RECEIVED_ZERO : Scales.R300_RECEIVED_ZERO))
{
Debug.WriteLine("[DEBUG] Read Zero from race " + scales.raceNumber + " dataLen: " + dataLen);
}
else
{
Debug.WriteLine("[DATA] (unknown) " + sensorData + " from serialport on race " + scales.raceNumber);
}
}
}
}
catch (System.IO.IOException ex)
{
SerialPort sp = (SerialPort)sender;
string msg = "[ERROR] SerialDataReceived " + (sp != null ? sp.PortName : "[unknown port]") + " - " + ex.Message;
Debug.WriteLine(msg);
TDUtils.WriteLog(msg);
}
}
< /code>
SerialPort (a .NET wrapper for the Win32 API), uses threadpool threads to call the DataReceived event handler. I was expecting these threads to be returned to the pool at the end of my handler. I suspect that some are not being returned - potentially caused by my Thread.Sleep(..).
I've seen many "solutions" to this but wondering which ones actually work and fit my scenario and how can I avoid using the Sleep to gather all the data before my next data request (write) is issued?
Подробнее здесь: https://stackoverflow.com/questions/794 ... lport-in-c
Как я могу избежать утечки ниток с чтением Serialport в C#? ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение