Как я могу избежать утечки ниток с чтением Serialport в C#?C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Как я могу избежать утечки ниток с чтением Serialport в C#?

Сообщение Anonymous »

У меня есть приложение, которое запрашивает ответ от 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
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»