none
IOException when reading serial port using .NET 2.0 SerialPort.Read.

    Question

  •  

    I have been getting the "The I/O operation has been aborted because of either a thread exit or an application request." exception when I try to read the serial port from a very simple application.

     

    My device sends tons of data without any kind of request/response.  The data is binary, so I do not want to use the ReadExisting method because of the encoding.  However, if I use the ReadExisting, it works without throwing this exception.

     

    I have tried with various timeouts, but this problem still occurs.  I think something tricky is going on in the background with the buffering of data that causes this threading error.  I do not have any additional threads in this app (beyond what is in a normal Windows forms app) and I have not called a "Close" on the port.

     

    I've been reading lots of posts, but I have not yet found an answer to this.

     

    serialPort1 = new SerialPort();

    serialPort1.BaudRate = 56000;

    serialPort1.ReadTimeout = 500;

    serialPort1.WriteTimeout = 500;

    serialPort1.Parity = Parity.None;

    serialPort1.DataBits = 8;

    serialPort1.StopBits = StopBits.One;

    serialPort1.PortName = "COM1";

    serialPort1.Open();

     

    byte[] readBuffer = new byte[100];

    serialPort1.Read(readBuffer, 0, 100);

     

    The exception detail is as follows:

    System.IO.IOException was unhandled
      Message="The I/O operation has been aborted because of either a thread exit or an application request.\r\n"
      Source="System"
      StackTrace:
           at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
           at System.IO.Ports.SerialStream.BeginReadCore(Byte[] array, Int32 offset, Int32 numBytes, AsyncCallback userCallback, Object stateObject)
           at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count, Int32 timeout)
           at System.IO.Ports.SerialStream.Read(Byte[] array, Int32 offset, Int32 count)
           at System.IO.Ports.SerialPort.Read(Byte[] buffer, Int32 offset, Int32 count)
           at LCD3Test.LCD3Test.btnStartComms_Click(Object sender, EventArgs e) in C:\CodeProjects\LCD3Test\LCD3Test\LCD3Test.cs:line 57
           at System.Windows.Forms.Control.OnClick(EventArgs e)
           at System.Windows.Forms.Button.OnClick(EventArgs e)
           at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
           at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
           at System.Windows.Forms.Control.WndProc(Message& m)
           at System.Windows.Forms.ButtonBase.WndProc(Message& m)
           at System.Windows.Forms.Button.WndProc(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
           at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
           at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
           at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
           at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
           at System.Windows.Forms.Application.Run(Form mainForm)
           at LCD3Test.Program.Main() in C:\CodeProjects\LCD3Test\LCD3Test\Program.cs:line 17
           at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
           at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
           at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()


    Wednesday, July 25, 2007 8:41 PM

Answers

  • Well, either threading or calling SerialPort.Close() just before Open() could half-way explain it.  You've already eliminated those causes.  The generic diagnostic is that the ReadFile() API function returns ERROR_OPERATION_ABORTED.  Calling CancelIO() could do this but there isn't any candidate code that would call this API function.  If you are 100% sure that it isn't a Close() call, you'll need to start suspecting the serial port driver.  Especially when you're using some kind of USB device, their drivers are often quite buggy.  Look for updated drivers at the manufacturer's web site.  Try other hardware.
    Thursday, July 26, 2007 12:59 PM
    Moderator

All replies

  • Well, either threading or calling SerialPort.Close() just before Open() could half-way explain it.  You've already eliminated those causes.  The generic diagnostic is that the ReadFile() API function returns ERROR_OPERATION_ABORTED.  Calling CancelIO() could do this but there isn't any candidate code that would call this API function.  If you are 100% sure that it isn't a Close() call, you'll need to start suspecting the serial port driver.  Especially when you're using some kind of USB device, their drivers are often quite buggy.  Look for updated drivers at the manufacturer's web site.  Try other hardware.
    Thursday, July 26, 2007 12:59 PM
    Moderator
  •  

    This was are regular serial COM port (not USB) on my brand-new Dell machine.  It had a Microsoft Driver version 5.1.2600.0.  I don't know what could be wrong with this, but I put another serial port card in the machine and I don't have the IOException problem with that port.

    I was skeptical, but nobugz had the answer.  Thanks.

    Thursday, July 26, 2007 7:21 PM
  • Hmm, I'm sceptical too.  The Microsoft driver is solid.  If you really want to be sure, put the old card back.
    Thursday, July 26, 2007 7:28 PM
    Moderator
  • Sorry to bump an old post but I'm having the same problem. Except all I get from the debugger is

    An unhandled exception of type 'System.IO.IOException' occurred in System.dll
    Additional information: The I/O operation has been aborted because of either a thread exit or an application request.

    I'm running the port at 9600/8/N/1, a received bytes threshold of 3 bytes and a read timeout of 2000. Everything else is default. The 3rd byte of the data I read in contains the number of expected remaining bytes, which I then read in afterwards. I'm using the onboard COM ports using driver 5.1.2600.

    The problem arises when I tried to read the 3 byte header of the total message, so I've rule out any timing issues with the rest of the message arriving. It also occurs consistently on the 4th message received. When I look at the read in byte array, it's all zeroes even though the expected data is non-zero. Looking at the serial port, in this particular message, all 9 expected bytes are still waiting to be read. I know there are meant to be 9 bytes as I have a sniffer cable on the data lines and can see the data pass through. Disconnecting it has no impact on the problem, so it's not a signal level issue.

    What I don't understand is that the receive data event is being fired, so it must have received 3 bytes. Even if the 3rd byte hadn't come in, the receive timeout is set to 5000 ms, which is huge and the program doesn't wait that long before throwing the error. So if the event is being fired as 3 bytes are there, what causes it to throw the error? I have written a similar program that uses the readline command instead of the read command and I haven't had any problems with that program. This particular program, when being tested by simulated responses, it performed flawlessly. But now it is connected to the device that the program was written for. It almost seems like the device is taking too long to send the message but like I said before, the timeout is at 5000ms, which it definately isn't reaching.

    I'm going to try and handle the timing from within my code and see how it goes, but until then, hopefully there is something I've written that will shed some light on the problem, considering that the IOException isn't listed as an exception in the SerialPort.Read instruction.

    Sunday, February 14, 2010 10:12 PM
  • Well I don't have a solution but have figured a work around. I start by using System.Threading.Thread.Sleep(500) just before I use  this.SerialPort.read... As the data received event is triggered on a separate thread to the UI thread, there is no risk of lock up. This just ensures that the data really has come in and probably isn't even necessary. Then before I read, I check that there are the minimum number of bytes available to be read (in my case, 3). If there aren't, in the case of when the error was being thrown, I simply don't read them in. Due to the fact that I'm looking for very specific messages and because my comms uses CRC16, it will inevitably fail, flag it as a failure, clear the receive buffer and retransmit the message.

    This works for me and my comms are stable... for the moment. I can understand this approach is probably less than ideal if you have 2 DTE's and are transferring a lot of data, but my comms are in no rush to achieve their goal and it seems an appropriate response to an error that doesn't exist according to the .NET 2.0 help file. But hey, this may have been corrected in later versions of .NET.
    Monday, February 15, 2010 12:39 AM
  • ScubaS2

    Have you remembered a routine to close SerialPort? If not, the automatic garbage collector of .Net may close it for you while the port is still in use. In that case, you will get such an exception.

    SerialPort works fine as long as you don't need to use the modem control signals. No Sleep() is needed except if you want to close and reopen the port.

    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.
    Monday, February 15, 2010 7:22 AM
  • I tried SerialPort in .NET for the first time yesterday and encountered IOException too.

    I've managed to rootcause it though. If anyone's interested, you might want to read this - http://zachsaw.blogspot.com/2010/07/net-serialport-woes.html .

     

    • Proposed as answer by akerd Wednesday, July 16, 2014 8:56 AM
    Thursday, July 01, 2010 8:48 AM
  • Thanks very much Scuba. We're receiving NMEA type sentences into software and this works very nicely.

    Thank you.

    Saturday, April 27, 2013 5:14 PM