Click here to Skip to main content
15,886,633 members
Home / Discussions / C#
   

C#

 
GeneralRe: Select data from MSSQL database and insert into oracle database Pin
Member 1346617612-Jan-18 3:36
Member 1346617612-Jan-18 3:36 
GeneralRe: Select data from MSSQL database and insert into oracle database Pin
Richard Deeming12-Jan-18 3:45
mveRichard Deeming12-Jan-18 3:45 
GeneralRe: Select data from MSSQL database and insert into oracle database Pin
Member 1346617612-Jan-18 4:01
Member 1346617612-Jan-18 4:01 
QuestionSystem.IO.IOException: 'The I/O operation has been aborted because of either a thread exit or an application request Pin
Member 1058555811-Jan-18 11:19
Member 1058555811-Jan-18 11:19 
AnswerRe: System.IO.IOException: 'The I/O operation has been aborted because of either a thread exit or an application request Pin
OriginalGriff11-Jan-18 11:25
mveOriginalGriff11-Jan-18 11:25 
AnswerRe: System.IO.IOException: 'The I/O operation has been aborted because of either a thread exit or an application request Pin
Bernhard Hiller11-Jan-18 21:35
Bernhard Hiller11-Jan-18 21:35 
GeneralRe: System.IO.IOException: 'The I/O operation has been aborted because of either a thread exit or an application request Pin
Member 1058555812-Jan-18 3:19
Member 1058555812-Jan-18 3:19 
AnswerRe: System.IO.IOException: 'The I/O operation has been aborted because of either a thread exit or an application request PinPopular
Luc Pattyn12-Jan-18 5:16
sitebuilderLuc Pattyn12-Jan-18 5:16 
Hi,

serial ports are tricky; and SerialPort documentation is missing a lot of info. I have lots of experience with SerialPort, and I happen to have read four articles about them just yesterday (more later).

I don't know for sure what is wrong in your situation, however I'll give you some pointers to critical aspects. I do expect you have two different issues, a receive issue and a close issue, and they are probably linked.

1. Encoding: as long as everything is ASCII (i.e. bit7 is zero in every byte), all is well. Whenever you need 8-bit (or 16-bit or 32-bit) characters, make sure SerialPort.Encoding is set correctly, it is used in Read() and Write(), unless you use the byte[] ones. Do not trust the default encoding.
You can use ISO 8859-1 for pass-thru:
port.Encoding=Encoding.GetEncoding(28591);


2. EndLine: you don't use WriteLine() yet you use ReadLine()? That is odd. And may well indicative to the cause of your receiver problem: whatever SerialPort.EndLine is set to will be sent as terminator in WriteLine(), and will be looked for in the incoming data to determine when ReadLine() gets satisfied.
Since you did not use WriteLine() I am guessing you didn't like the endline terminator, but yet you are waiting for it to be sent in DataReceived???

It is very well possible tht your peripheral uses ASCII CR (you send it explicitly!) but never sends ASCII LF, and if the default EndLine is set to CR-LF, ReadLine will never return a thing...

Remember, a terminal emulator isn't very good at reporting non-printable characters such as CR and LF

3. The DataReceived event: this is the most misunderstood event I ever saw; people seem to think it will fire on every incoming byte. It won't. People like to think it will fire after every incoming message (whatever that means), it doesn't. Here is the one correct statement: provided some data got received (any number of bytes), it will fire at least once; everything else is speculation.

As a result, when your peripheral sends three bytes ("5" "2" CR) you might get two DataReceived events, one with data "5", the other with "2" CR.

4. the DataReceived handler should not be blocking; most examples correctly consume "whatever is available" and make sure the handler is done right away, so the thread gets freed, and a new DataReceived event can be processed. (Behind the scenes, SerialPort made sure no two handlers can be active at the same time, someting they fail to tell explicitly).

Your handler does the opposite: it contains a blocking ReadLine().

There is another weakness: as you display the datain a TextBox, you'll see at most one line, so if [5 2 CR LF CR LF] were to be received, you would see nothing, the empty line would overwrite the 52 right away.


The correct way to handle DataReceived in general is like so:
- create a buffering scheme (it will need a lock!)
- add incoming data to the buffer; this should be the only data manipulation inside the DataReceived handler;
- make sure the lock is mostly free, if not your handler becomes blocking which it shouldn't!
- create a way to process the buffer, do this outside the DataReceived handler (in a background thread), possibly signalled by the DataReceived handler.

In specific cases, a much simpler approach can work just fine. A simple case would be: only short messages (with known upperbound lenght) and a guaranteed gap in between messages. If so, I would create a DataReceived handler that is very blocking: it starts with a Thread.Sleep to make sure the message is completely received, then process it right away (preferrably with Read, not ReadLine, as that may block forever).

5. Closing the port. Quite often one has a permanent receiver, your program wants to catch whatever comes in, whenever it does. That makes it harder to close the port, as you cannot perform a Close() while a Read or Write is in progress. That would throw the exception you are getting. Quite often the solution is not to close the port at all. Or set a timeout on the port so a Read doesn't block forever, and wait for at least that time just before closing the port (don't expect the timeout to work accurately though, it can be of a lot). Of course, a receiver with a timeout, will detect a "no data" situation and may be inclined to launch another Read, a boolean should prevent that when you intend to close the port. I also have seen, but never felt the need for, code that created a background thread just to close the serial port (catching and ignoring any exception when that fails).

6. Thread safety: the doc is a joke; statics are thread safe, and the other methods aren't. If true, SerialPort would be useless, e.g. Read and ReadLine would not be allowed in the DataReceived handler!!!




In summary: it is my guess your ReadLine fails on a mismatched EndLine situation, and your program bombs on closing the port while a read is in progress.

What I tend to do except for the simplest cases (this was true long before .NET, the native serial port has similar pitfalls):
- use binary port operations (i.e. byte[]) rather than text as much as possible;
- use an explicit endline, i.e. avoid using ReadLine and WriteLine;
- use a dedicated background thread to periodically consume (i.e. move to my buffer) incoming data, foregoing DataReceived alltogether.

Two extra suggestions:
- it doesn't hurt putting difficult code inside a try-catch construct, and reporting any exception that might occur.
- I tend to always log exceptions to a text file, saves lots of time while developing a program, and helps in diagnosing a problem later on too.

Hope this helps.

Smile | :)


Additional reading:

https://social.msdn.microsoft.com/Forums/vstudio/en-US/e36193cd-a708-42b3-86b7-adff82b19e5e/how-does-serialport-handle-datareceived?forum=netfxbcl

https://blogs.msdn.microsoft.com/bclteam/2006/10/10/top-5-serialport-tips-kim-hamilton/

https://blogs.msdn.microsoft.com/bclteam/2006/05/26/serialport-encoding-ryan-byington/

https://blogs.msdn.microsoft.com/bclteam/2006/05/15/serialport-and-datareceived-event-ryan-byington/
Luc Pattyn [My Articles] Nil Volentibus Arduum


modified 12-Jan-18 11:33am.

GeneralRe: System.IO.IOException: 'The I/O operation has been aborted because of either a thread exit or an application request Pin
Member 1058555812-Jan-18 6:31
Member 1058555812-Jan-18 6:31 
GeneralRe: System.IO.IOException: 'The I/O operation has been aborted because of either a thread exit or an application request Pin
Luc Pattyn12-Jan-18 6:46
sitebuilderLuc Pattyn12-Jan-18 6:46 
QuestionC# How can I center the PictureBox to the Parent from code? ( Windows Forms ) Pin
Karl Henrry11-Jan-18 10:27
Karl Henrry11-Jan-18 10:27 
AnswerRe: C# HOW CAN I CENTER THE PICTUREBOX TO THE PARENT? Pin
Pete O'Hanlon11-Jan-18 10:45
mvePete O'Hanlon11-Jan-18 10:45 
GeneralRe: C# HOW CAN I CENTER THE PICTUREBOX TO THE PARENT? Pin
Karl Henrry11-Jan-18 12:26
Karl Henrry11-Jan-18 12:26 
AnswerRe: C# HOW CAN I CENTER THE PICTUREBOX TO THE PARENT? Pin
OriginalGriff11-Jan-18 11:14
mveOriginalGriff11-Jan-18 11:14 
GeneralRe: C# HOW CAN I CENTER THE PICTUREBOX TO THE PARENT? Pin
Karl Henrry11-Jan-18 12:41
Karl Henrry11-Jan-18 12:41 
AnswerRe: C# How can I center the PictureBox to the Parent from code? ( Windows Forms ) Pin
User 740747011-Jan-18 13:52
User 740747011-Jan-18 13:52 
GeneralRe: C# How can I center the PictureBox to the Parent from code? ( Windows Forms ) Pin
Karl Henrry11-Jan-18 14:12
Karl Henrry11-Jan-18 14:12 
QuestionBest Temporary storage for DataGrid in C# Pin
Member 1359640810-Jan-18 13:17
Member 1359640810-Jan-18 13:17 
AnswerRe: Best Temporary storage for DataGrid in C# Pin
OriginalGriff10-Jan-18 19:51
mveOriginalGriff10-Jan-18 19:51 
AnswerRe: Best Temporary storage for DataGrid in C# Pin
Eddy Vluggen11-Jan-18 1:03
professionalEddy Vluggen11-Jan-18 1:03 
Questionc# Introduction Pin
ormonds10-Jan-18 10:39
ormonds10-Jan-18 10:39 
AnswerRe: c# Introduction Pin
OriginalGriff10-Jan-18 19:49
mveOriginalGriff10-Jan-18 19:49 
GeneralRe: c# Introduction Pin
ormonds10-Jan-18 23:14
ormonds10-Jan-18 23:14 
GeneralRe: c# Introduction Pin
OriginalGriff10-Jan-18 23:25
mveOriginalGriff10-Jan-18 23:25 
AnswerRe: c# Introduction Pin
Richard MacCutchan10-Jan-18 22:28
mveRichard MacCutchan10-Jan-18 22:28 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.