UnauthorizedAccessException on Serial Port after pulling the plug
- I have an application that has a serial to USB connector. When I connect to a port and pulls the plug from the USB and then reconnect the application itself works fine but when I close the application, I get UnauthorizedAccessException and I cannot figure out where it is thrown. I tried to run it in debugger but still no lead on where it is. I even tried to do
and still, this exception was not caught anywhere.try { Application.Run(new MyApplication()); } catch (UnauthorizedAccessException e) { //Do something here }
What I want to achieve is to be able to handle the case when the application is connected to a port and then the plug the pulled or reconnected, the application should be able to handle it. Right now it crashes with that exception. I wonder if there is anyway to recover a lost COM port.
Thanks
Respuestas
- OK, found out exactly what the problem is and the workaround
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=140018
NOTE: the <legacyUnhandledExceptionPolicy enabled="1"/> posted by Microsoft no longer works with .NET Framework 3.5, I have yet to try any of other workout proposed.- Marcado como respuestaRudedog2Moderatorlunes, 09 de noviembre de 2009 21:21
- Editadoxenoverse lunes, 09 de noviembre de 2009 21:23
- Editadoxenoverse lunes, 09 de noviembre de 2009 21:26
- Editadoxenoverse lunes, 09 de noviembre de 2009 21:25
Todas las respuestas
- No doubt there is, but first things first. Why the exception?
Is your port being accessed through threads?
That could cause the behavior you describe.
A thread exception being thrown when it tries to reference a disposed, unmanaged resource like a disconnected port.
And it seems your threads can keep running even after the application has closed. Gotta clean that up if that is the case.
Mark the best replies as answers. "Fooling computers since 1971." I think the exception is thrown as the BaseStream of the SerialPort is being finalized when the plug is pulled. I've managed to overcome this error by adding a GC.SuppressFinalize call after calling SerialPort.Open, and then calling GC.ReregisterForFinalize (i think) method before i call SerialPort.Close. When doing this, i've never seen the exception occur again.
Hope this helps
Kev- ... or maybe i've got that wrong, it may be that you call GC.SuppressFinalize before Open and GC.ReRegisterForFinalize after Close.
As an extra comment, so far i've never been able to trap the UnauthorizedAccessException that is throw
Kev
There are just a couple of methods that can throw that exact esception.
SerialPort.Open();
SerialPort.Close();
Those are two of the most prominent ones.
Most of the class members throw InvalidOperationExceptions.
I would the actual hardware interaction is being done under a different thread.
That might explain why some of those exceptions are so hard to catch.
Mark the best replies as answers. "Fooling computers since 1971."- The actual hardware interaction is done on the main thread. The problem is that when the main form is closed, I think, the system tries to release all the resources, including the comPort. But if the comPort was connected and then the line was physically unplugged, then the port is no longer there, thus this exception.
I wrote a very simple program to test it out, and it was still giving me this error without any indication of where it was thrown.
Given this program, load it, make sure COM3 has something connected, while it is connected, unplug the line and then close the program, the UnauthorizedAccessException will be thrown.namespace WindowsFormsApplication1 { public partial class Form1 : Form { private SerialPort comPort = new SerialPort(); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { comPort.PortName = "COM3"; comPort.Open(); }
- I tried GC.ReRegisterForFinalize and GC.SuppressFinalize but the error is still showing up.
- The *actual* hardware interaction is probably being done on another thread.
I believe that the port itself generates the thread, not you.
Subscribe to the Form_Closing event and call this stuff.
port.Close();
port.Dispose();
Make sure the port is closed and disposed before the form closes.
Mark the best replies as answers. "Fooling computers since 1971." - I have subscribed to the Form_Closing event and that, unfortunately, does not stop the error from popping up.
And you say that you have nothing running on any threads that you created yourself?
I have no means to reliably test serial ports. This didn't throw any exceptions when the form was closing.
serialPort2.Close();
serialPort2.Dispose();
while (serialPort2 != null)
{
}
return;
Mark the best replies as answers. "Fooling computers since 1971."I think the exception is thrown as the BaseStream of the SerialPort is being finalized when the plug is pulled. I've managed to overcome this error by adding a GC.SuppressFinalize call after calling SerialPort.Open, and then calling GC.ReregisterForFinalize (i think) method before i call SerialPort.Close. When doing this, i've never seen the exception occur again.
Hope this helps
Kev
What about this?
Mark the best replies as answers. "Fooling computers since 1971."- I tried to put GC.SuppressFinalizeand GC.ReregisterForFinalize to where Kev suggested but that exception still shows up.
I also tried
serialPort2.Close();
serialPort2.Dispose();
while (serialPort2 != null)
{
}
return;
but this just puts the application into the infinite loop when I try to close the form.
And yes, the threads that I created wasn't doing anything at all. I tested both of your suggestions in the simply program I posted above, with only 1 button and open a fixed port. - Then the port is never getting disposed. My form closes with that while loop.
Mark the best replies as answers. "Fooling computers since 1971." - This may help http://www.codeguru.com/forum/showthread.php?p=1893290
Can you post any more of your code?
I have had trouble with this exception before, however the GC.SuppressFinalize and GC.ReRegisterForFinalize DID fix the problem - i'm puzzled as to why it hasn't made a difference in this instance. Could be the driver i guess, as we use FTDI-based devices, although having said that, we have also used other non-FTDI devices as the code still works without exception.
If it helps, i can post some of my code to try
Kev- OK, found out exactly what the problem is and the workaround
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=140018
NOTE: the <legacyUnhandledExceptionPolicy enabled="1"/> posted by Microsoft no longer works with .NET Framework 3.5, I have yet to try any of other workout proposed.- Marcado como respuestaRudedog2Moderatorlunes, 09 de noviembre de 2009 21:21
- Editadoxenoverse lunes, 09 de noviembre de 2009 21:23
- Editadoxenoverse lunes, 09 de noviembre de 2009 21:26
- Editadoxenoverse lunes, 09 de noviembre de 2009 21:25
- I guess this is just one that Microsoft have swept under the carpet.
- Can some one repost the link I posted and I'll mark that as an answer so anybody who has this problem in the future will have an easier time to find the solution. BTW, Microsoft said it should be fixed in the next major release of .NET Framework, which should be 4.0 with a scheduled release date of March 22, 2010. So this shouldn't be too long.
Here is the link, if someone could post it again.
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=140018
- EditadoRudedog2Moderatorlunes, 09 de noviembre de 2009 21:22corrected link
- Work around?
I think if you write a DLL that targets the .NET 2.0 framework that does all of that stuff, you should be good.
Mark the best replies as answers. "Fooling computers since 1971." - I know this post is already marked as answered but just as an update - the GC.SuppressFinalize and GC.ReRegisterForFinalize should be called passing the SerialPort instance BaseStream property as the parameter and not just the SerialPort instance.
I've been having a play with this at work today and definitely no exception is generated with this code, whereas an exception is thrown without the code.
Kev I know this post is already marked as answered but just as an update - the GC.SuppressFinalize and GC.ReRegisterForFinalize should be called passing the SerialPort instance BaseStream property as the parameter and not just the SerialPort instance.
I've been having a play with this at work today and definitely no exception is generated with this code, whereas an exception is thrown without the code.
Kev
Thanks for the update.
Your efforts are much appreciated.
Mark the best replies as answers. "Fooling computers since 1971."

