I am writing an application that uses virtual (shared) serial ports via a USB to RS232 adapter. If the user accidentally disconnects the USB adapter, my data stream stops (occasionally throwing an IO exception but not always). Normally, the user could just reconnect the port and the listener would continue. But all of the virtual port applications I have found need to be reset, then then my application must be re-initialized. I could put a read timeout in my listener but I'm curious if there isn't a clean way to detect the ports use the property changed event handler. Since it's a virtual port, I don't believe using hardware level commands will work. I have achieved the detection in a console app just using a while loop where I continually poll the ports using GetPortNames. But that just isn't practical in a forms app using a DataReceived Event Handler, especially considering all the parsing I do on the data stream. I have searched multiple sites (including this one) and no one has adequately addressed the issue. Please, any help appreciated.
Related
I have a program then when started looks for the serial ports available on the computer and if found would try to open those and listen to those for data.
As of now, I have a configuration file that has got all port settings along with the Port Number to listen to.
At first run I get the user to first enter the POrt No. on which the device is connected. That is recorded into the Config and is used from there one.
I would now like to change that so that when started, it scans the ports and gets the list of Serial Ports available. That part I can do with SerialPort.GetPortNames() method.
However, now I would like to ping each port and check which one has the device connected, open that port and keep listening to that port.
I can check with my device manufacturer to get the commands to ping and ACK back from device.
My Question to the experts is
Is it correct (archietecturally/technically) to keep the ports open all the time
Should that be done in a seperate thread and probably keep the thread for just serial port communications while main thread does all other jobs.
What if there are multiple devices connected to same PC. Should we keep seperate threads for each device ?
Any help or ideas would be greatly appreciated.
Thanks
Ashutosh
Is it correct (archietecturally/technically) to keep the ports open
all the time
It's normal to do that. Continually opening and closing ports is an expensive and wasteful operation. Sometimes is is used as a message framing protocol, ie. open/send/close, but a protocol that keeps the port open is surely going to perform better.
Should that be done in a seperate thread and probably keep the thread
for just serial port communications while main thread does all other
jobs.
It can be, yes. I have used such a design - create threads that attempt to open COM1-COM9 and, if the open succeeds, try to communicate with a peripheral. If the comms is successful, the handler thread messages the main thread with an object reference/pointer that can be used to communicate with the port, (and usually give user feedback, eg. check a checkbox and change its background colour from red to green).
What if there are multiple devices connected to same PC. Should we
keep seperate threads for each device ?
That's how I usually handle it, yes. I define a class that represents the port, it's protocol and state. Each port-handler thread then creates its own instance and so each port gets handled independently.
I have application to communication with device. Device is connected through serial COM port. My app can comunicate with device.
I need some method / event, that can scan COM ports through running app. When I'll connect device to PC - method / event will print MessageBox with message "connected", or something like that.
I found something like this:
comPort.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
But it doesnt work.
I'm not sure if you are trying to auto-detect which port a device is connected to, or auto-detect whether a device is connected to a specific port.
In both cases though, the principle is the same:
you enumerate the the serial ports using: SerialPort.GetPortNames if you need to determine the port, or skip to the Step 2 if you already know the port
for each port in the collection you open a connection by creating a new SerialPort object for it, and by calling Open
for each open connection you attempt to write/read from the port the sequence of data that determines whether your device is attached
for each open connection if the data read times out then there is no device attached to the port; otherwise, if you get back what you expect you know your device is attached
for each port, close the connection using Close on the SerialPort object.
Performing the above at any given point will tell you whether your device is attached at that point, and which port it is attached to.
If you need to do presence detection continuously, then you will probably want to create a timer and perform this test periodically (every 30 seconds, or every 2 minutes - depending on the latency you are willing to accept).
NOTE
As others have indicated in the answers, you will want to run the serial port detection code asynchronously so as not to block your main application while scanning the ports. The scanning is guaranteed to take a while because of the time-outs of the ports that have no device attached.
I have a c# .net4 application that listens on a socket using BeginReceiveFrom and EndRecieveFrom. All works as expected until I put the machine to sleep and then resume.
At that point EndReceieveFrom executes and throws an exception (Cannot access a disposed object). It appears that the socket is disposed when the machine is suspended but I'm not sure how to handle this.
Do I presume that all sockets have been disposed and recreate them all from scratch? I'm having problems tracking down the exact issue as remote debugging also breaks on suspend/resume.
What happens during suspend/resume very much depends on your hardware and networking setup. If your network card is not disabled during suspend, and the suspend is brief, open connections will survive suspend/resume without any problem (open TCP connections can time out on the other end of course).
However, if your network adapter is disabled during the sleep, or it is a USB adapter that gets disabled because it is connected to a disabled hub, or your computer gets a new IP address from DHCP, or your wireless adapter gets reconnected to a different access point, etc., then all current connections are going to be dropped, listening sockets wil no longer be valid, etc.
This is not specific to sleep/resume. Network interfaces can come up and go down at any time, and your code must handle it. You can easily simulate this with a USB network adapter, e.g. yank it out of your computer and your code must handle it.
I've had similar issues with suspend/resume and sockets (under .NET 4 and Windows 8, but I suspect not limited to these).
Specifically, I had a client socket application which only received data. Reading was done via BeginReceive with a call-back. Code in the call-back handled typical failure cases (e.g. remote server closes connection either gracefully or not).
When the client machine went to sleep (and this probably applies to the newer Windows 8 Fast Start mode too which is really just a kind of sleep/hibernate) the server would close the connection after a few seconds. When the client woke up however the async read call-back was not getting called (which I would expect to occur as it should get called when the socket has an error condition/is closed in addition to when there is data). I explicitly added code on a timer to the client to periodically check for this condition and recover, however even here (and using a combination of Poll, Available and Connected to check if the connection was up) the socket on the client side STILL appeared to be connected, so the recovery code never ran. I think if I had tried sending data then I would have received an error, but as I said this was strictly one-way.
The solution I ended up using was to detect the resume from sleep condition and close and re-establish my socket connections when this occurred. There are quite a few ways of detecting resume; in my case I was writing a Windows Service, so I could simply override the ServiceBase.OnPowerEvent method.
I have a USB device (e.g. barcode scanner etc.)
I communicate with it using SerialPort (which is found nicely from toolbox of VS2008)
My problem is:
After starting my PC when starting my application for the first time it is hanging up or stuck up or going into not responding mode when it tries to sending a string to the serial port.
To come out of it I just remove the USB cable from the USB port of my PC.
As soon as I remove the cable I getting below error message:
If I press the Continue button plug the removed USB cable back in my application working fine.
Note: I am getting this error only when I start my app first time after starting or restarting my PC. Afterwards it's working fine as I wanted.
Note: Another thing to consider is that if I put my code in try and catch
I catch the exception only when I remove the USB cable from my PC.
Edit:
After restarting my PC, if I do
plug out and then plug in the USB cable from the USB Port of the PC, and then
I start my App then it's working fine
It seems to me that the control is going inside an infinite loop when i try sending a string to the serial port at the very first time after starting of the PC.
See the details of my code over here
The 90% odds here are that you are trying to work around a common deadlock scenario with SerialPort. It is common to get triggered when you use Invoke() in your DataReceived event handler. If you then use Close() in your main thread while the port is busy receiving data then a deadlock is common. Close cannot complete until the DataReceived event handler completed running, Invoke() cannot complete because the main thread is stuck in the Close call. Jerking out the connector works because the ThreadExceptionDialog pumps messages, allowing the Invoke to complete.
A simple workaround is to use BeginInvoke() instead. Just not calling Close is fine too, Windows takes care of it when your program terminates. Some sort of controlled shutdown of your app so that you don't lose anything sent by the serialport device is best.
You must close the serial port in the FormClose event. Because, port is once open your application and close the port on the application end
I am using a serial port communication C# windows application. I wrote a program to get the data from the port, to manipulate it and write through the serial port.
My question is in case the unit is not powered on, the power supply is disconnected, or the unit is not responding to commands for a long time, how will I know? In my program, I have written for normal flow of execution. But in case there is no response for long time, the program keeps on waiting for a long time. I used a timer but it doesn't work properly.
Can anyone help me please?
If you are using the "SerialPort" object in C#, then you can use the ReadTimeOut and WriteTimeOut Properties.
You've got two options:
If you have a device which should be generating data you can listen on the serial port for data from and if nothing is received for a set period you can assume it is offline,
Periodically send data to your device over the serial port and if you get an exception then you will know your device is offline.
One thing that might help is if the cable you are using is wired with DTR / DSR crossed, meaning that when your program starts you raise DTR and the other device see's DSR go high, and in turn raises it's DTR, which raises your DSR.
If you are using unknown cables and communicating with devices you don't have control over, then you will have to use .Timeout.