Good morning everyone,
I created a WebApi application (Framework 4.5) that exposes web services through which desktop clients request data.
On the server side (where the WebApi is present) the devices are queried via the serial port (on separate threads) and update the data which the client will then request.
I wanted some advice from you on what is the best technique for reading serial ports from a web application without the WebApi being blocked.
At the moment for each device whose data I have to read I create a new thread and everything works quite well, but I would like to know (also perhaps with your past experiences) if there are better techniques.
Thank you
Marco MorgiaPosted Apr 8, 2024, 10:20 AM
Thanks everyone for the replies.
Instead I would like to know when to launch the Thread which then launches the sub-threads for reading the COM ports for each device?
An instance of ImplementBackgroundService (which implements the BackgroundService interface) is currently launched in the WebApiConfig.cs file. In the override of the ExecuteAsync method I start the subthreads for the COM read devices
Is this a correct solution?
Mukesh NailwalPosted Apr 8, 2024, 9:20 AM
One common problem is to read serial ports from a web application (like your ASP.NET WebApi) without causing the server to go down. While your implementation of using different threads for each device is a good approach, there are additional methods you may want to think about. Here are some recommendations:
Asynchronous I/O: Use the asynchronous programming methods that.NET offers to carry out non-blocking input/output activities. In the meantime, as your application waits for data from the serial port, it can continue responding to requests. Using the ReadAsync() function, you can use the SerialPort class asynchronously. This method can increase scalability and simplify your code.
using System.IO.Ports;
using System.Threading.Tasks;
public class SerialPortReader
{
private SerialPort serialPort;
public SerialPortReader(string portName, int baudRate)
{
serialPort = new SerialPort(portName, baudRate);
serialPort.Open();
}
public async Task ReadDataAsync()
{
return await serialPort.ReadLineAsync();
}
}
Task Parallel Library: Higher-level abstractions for controlling asynchronous operations are offered by the Task Parallel Library, or TPL. Task is available for use.To run methods on the thread pool asynchronously, use Run(). Features like exception management and cancelation are also provided by TPL.
using System.Threading.Tasks;
public class SerialPortReader
{
private SerialPort serialPort;
public SerialPortReader(string portName, int baudRate)
{
serialPort = new SerialPort(portName, baudRate);
serialPort.Open();
}
public void ReadData()
{
Task.Run(async () =>
{
while (true)
{
string data = await serialPort.ReadLineAsync();
// Process data
}
});
}
}
Thread Pooling to Manage Concurrent Tasks: To handle concurrent tasks, you can use the thread pool rather than starting a new thread for every device. By doing this, you may limit the amount of concurrent processes and prevent resource depletion. The ThreadPool.QueueUserWorkItem() function can be used to carry out asynchronous task execution.
using System.Threading;
public class SerialPortReader
{
private SerialPort serialPort;
public SerialPortReader(string portName, int baudRate)
{
serialPort = new SerialPort(portName, baudRate);
serialPort.Open();
}
public void ReadData()
{
ThreadPool.QueueUserWorkItem(async (_) =>
{
while (true)
{
string data = await serialPort.ReadLineAsync();
// Process data
}
});
}
}
Select the method that best suits the needs and architecture of your program; however, to keep your web site stable and dependable, make sure that error handling and resource cleanup are done correctly.
Drop a comment if still need any help!
Thanks
Jayraj ChhayaPosted Apr 8, 2024, 9:12 AM
When dealing with reading serial ports in a web application like a WebApi, it's crucial to ensure non-blocking operations to maintain responsiveness. While creating separate threads for each device works, it can lead to scalability and resource management issues.
One recommended approach is to use asynchronous programming in .NET to handle serial port communication efficiently. By utilizing asynchronous methods like
ReadAsyncandWriteAsyncfrom theSerialPortclass, you can read data without blocking the main thread.