title: System.IO.IOException: A device attached to the system is not functioning C# .NET 4.0
body: <p>I've built a C# application which reads and writes data from a serial port. The device connected to the serial port is a FTDI USB to serial converter which communicates to hardware through a XBee wireless module. The hardware tests battery modules for capacity and steady state voltage etc. these tests take days to complete.</p>
  
  <p>Every now and then the serial port seems to stop responding and throws a System.IO.IOException: A device attached to the system is not functioning error.</p>
  
  <p>Here is the stack trace:</p>
  
  <pre><code>at system.IO.Ports.InternalResources.WinIOError
  at system.IO.Ports.SerialStream.EndWrite
  at system.IO.Ports.SerialStream.Write
  at system.IO.Ports.SerialPort.Write
  at BatteryCharger.CommunicationClass.ApiTransmission
  </code></pre>
  
  <p>after this error is thrown a <code>System.UnauthorizedAccessException: Access to the port is denied</code> error is thrown and this error occurs every time the software tries to write to the port and it never recovers until i stop debugging and restart the software only for the same thing to happen a few days later.</p>
  
  <p><strong>How do I prevent this error from occurring or is there a way to successfully recover from these errors in the catch statement of the error?</strong></p>
  
  <p>I'm reading the serial port continuously in a background worker thread and writing from a different thread.</p>
  
  <p>I've also already tried all the legacy error handling bits and pieces that have been suggested on this forum but none of them seem to make any difference. The error occurs on windows XP Pro SP3 32bit and Windows7 Pro 32bit.</p>
  
  <p>Here is the CommunicationClass.cs - serial transmission code.</p>
  
  <pre><code>    public static bool ApiTransmission(TXpacket transmission)
      {
          //clear all previous data that may have been in the buffer before doing a transmission
          Variables.dataParserPacket_buff.Clear();
          //TXpacket xbeetransmision = new TXpacket();
          byte[] packet = transmission.GeneratePacket();
  
          try
          {
              if (_serialPort.IsOpen)
              {
  #if Console
                  Log.write("TX-Packet: " + StringHandler.listToString(packet.ToList&lt;byte&gt;()));
  #endif
                  _serialPort.Write(packet, 0, packet.Length);
                  Thread.Sleep(100);
              }
              else
              {
  #if Console
                  Log.write("serial port is closed");
  #endif
                  return false;
              }
          }
          catch (UnauthorizedAccessException ex)
          {
              MessageBox.Show(ex.ToString());
              Log.write("UnauthorizedAccessException");
          }
          catch (IOException ex)
          {
              MessageBox.Show(ex.ToString());
              Log.write("IOexception");
              //_serialPort.Close();
              //Thread.Sleep(100);
              //_serialPort.Open();
          }
          catch (Exception ex)
          {
              MessageBox.Show(ex.ToString());
  #if Console
              Log.write(ex.ToString());
  #endif
          }
          return true;
  
      }
  </code></pre>
  
  <p>This is how I initialize my serial port</p>
  
  <pre><code>    public CommunicationClass(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits)
      {
          _analysePacketBGW.DoWork += new DoWorkEventHandler(_analysePacketBGW_DoWork);
          _analysePacketBGW.WorkerReportsProgress = true;
          _analysePacketBGW.WorkerSupportsCancellation = true;
  
          _readBGW.DoWork += new DoWorkEventHandler(_readThread_DoWork);
          _readBGW.WorkerSupportsCancellation = true;
          _readBGW.WorkerReportsProgress = true;
  
          _parserStarterBGW.DoWork += new DoWorkEventHandler(_parserStarterThread_DoWork);
          _parserStarterBGW.WorkerSupportsCancellation = true;
          _parserStarterBGW.WorkerReportsProgress = true;
          if (_readBGW != null)
          {
              _readBGW.CancelAsync();
          }
  
          _serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
  
          //SerialPortFixer.Execute(portName);
          //Thread.Sleep(1000);
          //using (_serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits))
          //{
          //    //_serialPort.Open();
          //}
  
          _serialPort.ErrorReceived += new SerialErrorReceivedEventHandler(_serialPort_ErrorReceived);
  
          _dataqueuepp = new ManualResetEvent(false);
  
          _serialPort.Open();
          _readBGW.RunWorkerAsync();
          _parserStarterBGW.RunWorkerAsync();
          CommunicationClass.PacketReceived += new DataPacketReceived(CommunicationClass_PacketReceived);
      }
  </code></pre>
  
  <p>And the background worker that handles the reading of the serial port</p>
  
  <pre><code>    void _readThread_DoWork(object sender, DoWorkEventArgs e)
      {
  #if Console
          Log.write("Read()");
  #endif
          while (!_readBGW.CancellationPending)
          {
              try
              {
                  int message = _serialPort.ReadByte();
                  try
                  {
                      Variables.dataQueue.Enqueue(message);
                  }
                  catch (Exception ex)
                  {
                      MessageBox.Show(ex.Message + "     " + message.ToString());
                  }
                  _dataqueuepp.Set();
                  //Console.Write(String.Format("{0:X2}", message) + " ");
              }
              catch (TimeoutException) { Log.write("read timeout"); }
              catch (IOException) { Log.write("read IOException"); }
              catch (ThreadAbortException) { Log.write("read thread aborted"); }
              catch (Exception ex) { MessageBox.Show(ex.ToString()); }
              finally { }
          }
      }
  </code></pre>
  
  <p>I will now rewrite the code to read and write to/from the serial port from the same thread to see if that makes any difference.</p>
  
  <p><strong>EDIT</strong></p>
  
  <p>Based on Jim's comments I've added the following to the IOException Catch statement:</p>
  
  <pre><code>        catch (IOException ex)
          {
              MessageBox.Show(ex.ToString());
              Log.write("IOexception");
              _readBGW.CancelAsync();
              Thread.Sleep(100);
              _serialPort.Close();
              Thread.Sleep(100);
              _serialPort.Open();
              Thread.Sleep(100);
              _readBGW.RunWorkerAsync();
              _serialPort.Write(packet, 0, packet.Length);
          }
  </code></pre>
  
  <p>Hopefully by stopping the background worker's _serialPort.Read, closing the port, re-opening  the port, running the background worker again and attempting to write the same command again will be enough to successfully recover from this error. The MessageBox still blocks the code so that i can see when the error occurs and can monitor how it recovers.</p>
  
  <p>I don't like patching software like this but if it works then it works.</p>
  
  <p><strong>EDIT 2</strong></p>
  
  <p>After adding the code above my software crashed again but now it throws an "UnauthorizedAccessException - Access to the port is denied" when i call _serialPort.Close();</p>
  
  <pre><code>System.UnauthorizedAccessException was unhandled
  Message=Access to the port is denied.
  Source=System
  StackTrace:
  at System.IO.Ports.InternalResources.WinIOError(Int32 errorCode, String str)
  at System.IO.Ports.InternalResources.WinIOError()
  at System.IO.Ports.SerialStream.Dispose(Boolean disposing)
  at System.IO.Stream.Close()
  at System.IO.Ports.SerialPort.Dispose(Boolean disposing)
  at System.IO.Ports.SerialPort.Close()
  at BatteryCharger.CommunicationClass.ApiTransmission(TXpacket transmission) in E:\Mijn Documenten\Research\Copy of BatteryCharger_V12\BatteryCharger\CommunicationClass.cs:line 436
  at BatteryCharger.CommunicationClass.tx1(TXpacket packet, String callingMethod) in E:\Mijn Documenten\Research\Copy of BatteryCharger_V12\BatteryCharger\CommunicationClass.cs:line 356
  at BatteryCharger.XBee.setPin(String pinID, Byte status, XBee slave) in E:\Mijn Documenten\Research\Copy of BatteryCharger_V12\BatteryCharger\XBee.cs:line 215
  at BatteryCharger.XBee.setPins(Int32 pins, XBee slave) in E:\Mijn Documenten\Research\Copy of BatteryCharger_V12\BatteryCharger\XBee.cs:line 177
  at BatteryCharger.BatteryCharger.requestVoltage(Int32 block) in E:\Mijn Documenten\Research\Copy of BatteryCharger_V12\BatteryCharger\BatteryCharger.cs:line 595
  at BatteryCharger.BatteryCharger.requestVoltages() in E:\Mijn Documenten\Research\Copy of BatteryCharger_V12\BatteryCharger\BatteryCharger.cs:line 612
  at BatteryCharger.Form1.RunCommandOn(List`1 battList, Int32 command, Double lowerLimit, Double upperLimit) in E:\Mijn Documenten\Research\Copy of BatteryCharger_V12\BatteryCharger\Form1.cs:line 522
  at BatteryCharger.Form1.chargeBlock(Int32 blockNr, Double lowerLimit, Double upperLimit) in E:\Mijn Documenten\Research\Copy of BatteryCharger_V12\BatteryCharger\Form1.cs:line 689
  at BatteryCharger.Form1.&lt;btnCheckCapacities_Click&gt;b__13() in E:\Mijn Documenten\Research\Copy of BatteryCharger_V12\BatteryCharger\Form1.cs:line 619
  at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
  at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
  at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 
  </code></pre>
  
  <p>What is going on here?</p>