0

So I've been battling this issue for about a week now and think I know the issue but I don't want to report an answer there until I have it pegged down.

In a nutshell, I get an IOException when trying to use the SerialPort.Open() command. As it turns out, this is very common and most terminal programs actually do as well, but they simply ignore it. Please read my post above for the full tale. Now what I want to do is ignore the IOException but still open the serial port. I cannot do this with try/catch, or at least I don't know how.

I was wondering is there a way to try something and somehow state that "I know an issue will be thrown, it is a safe problem and I am choosing to ignore the exception and carry on with the task". To be clear, I don't want to ignore the error then move on. I want to ignore the error and still complete the operation.

Below is my best guess, but it doesn't work.

        try
        {
            serialPort1.Open();               
        }
        catch (System.IO.IOException)
        {
            MessageBox.Show("An IO Exception occurred.");
        }
        finally
        {          
            //SAFELY IGNORE ERROR AND DO TASK ANYWAY HERE
        }

If anyone could help me out with this I'd be most appreciative.

EDIT: If I just add the code serialport1.Open afterwards I get: Screenshot of IOException

This is basically the same thing that would happen without the try/catch. What I want to do is say I'm trying to do this: I don't care that it throws an error, do it anyway.

Community
  • 1
  • 1
tmwoods
  • 2,353
  • 7
  • 28
  • 55
  • It doesn't appear that serialPort1.Open() is going to successfully succeed if you just try it again. Nothing is changing at all, why would you expect different results? – offthat Feb 21 '13 at 23:24
  • Are you sure issue is with the finally block and not the code in that finally block? – CookieOfFortune Feb 21 '13 at 23:24
  • Are you saying that when you call Open() the serial port doesn't actually open because of the error? – user959729 Feb 21 '13 at 23:25
  • Yes, that is exactly what I am saying. – tmwoods Feb 21 '13 at 23:28
  • You can ignore exceptions, however you will still not have the serial port open. There are cases in which you would have to have nested try/catches, however this does not look to be the case. I would recommend trying to find an alternative way to access the serial port, you'll most likely have to do something lower level. – James Oravec Feb 21 '13 at 23:35
  • Can you post the code you have for initializing and setting up the properties of the `SerialPort` from the looks of the exception window your problem lies in the code prior to `SerialPort.Open` – JG in SD Feb 21 '13 at 23:54
  • Please read the full thread linked above. – tmwoods Feb 21 '13 at 23:58

3 Answers3

5

In general, if you have a line of code causing an exception, and there's additional work to be done whether or not the exception occurred, you should just use a catch, and put the stuff you want done anyway outside (after) the try/catch.


For your particular case (described in your other question), you are dealing with the horrible brokenness that is .NET System.IO.Ports.SerialPort. Opening the serial port succeeded, but SerialPort.Open is a complicated method that does a bunch of extra stuff, and insists on closing the port if any of that extra (and unnecessary) stuff fails. I've found other problems with System.IO.Ports.SerialPort as well (e.g. inability to open ports by their internal device name). IMO, the sooner you get rid of System.IO.Ports.SerialPort the better.

You can either p/invoke the Win32 Serial Port functions (CreateFile and the rest are here) or find someone who already wrote a wrapper library (I did, but it isn't available publically).

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • Sorry, that isn't really what I'm looking for. Please read the full question again in case of a misunderstanding. – tmwoods Feb 21 '13 at 23:31
  • @tmwoods: Now I see that you've said "ignore the IOException but still open the serial port" (before I focused on "still complete the operation", which I expected meant whatever part of your code didn't use the serial port). You can't. Your code can continue after opening the serial port failed, but the port isn't open, so you won't be able to do anything that requires an open serial port. To use a serial port, you first need to open it *successfully*. – Ben Voigt Feb 21 '13 at 23:38
  • Hmm. I default to the expertise of others as I am still new to C#, but I still feel like there has to be a way to get this done. For instance when you add myPort.DataReceived += new SerialDataReceivedEventHandler(myPort_DataReceived); it safely ignores an error that is caused by multi-threading. Is there a way to do this with other errors? Or is this simply the correct way of created a handler? – tmwoods Feb 21 '13 at 23:40
  • @tmwoods: The fact that you came across one error (cross-thread access to UI) that you could simply ignore and proceed, does not mean that all errors are meaningless. If opening the serial port failed, you cannot proceed to use the serial port as if there were no failure. You can only do things unrelated to the serial port. Or you can try again, like David suggested. – Ben Voigt Feb 21 '13 at 23:43
  • I guess the reason I think it can be done is because every terminal program that I use and analyze with a COM port monitor throws an identical error but somehow ignores it and I'd be willing to bet that at least one of them (I have tested 4 so far) is developed in C. I am still searching for a decent open source program that successfully connects to see the code. I just feel like admitting defeat is a big price to pay at this point for something that I feel must exist as part of the compiler and IDE. – tmwoods Feb 21 '13 at 23:48
  • @tmwoods: Ok, now I understand your issue, it has nothing to do with ignoring `IOException`. .NET `SerialPort.Open` is generating an exception for something that wasn't a fatal error, and closing the port. There's nothing you can do except get rid of .NET's library for serial port access and use the Win32 API instead. C# can p/invoke Win32 functions, or you can find another wrapper library that isn't so dumb as the one provided by Microsoft. – Ben Voigt Feb 21 '13 at 23:49
  • @tmwoods: Just FYI, the analyzer showed that opening the serial port succeeded. But the `System.IO.Ports.SerialPort.Open` method (stupidly) does a whole lot more than just open the serial port. `System.IO.Ports.SerialPort` has a LOT of problems, I only looked at it for under an hour before I decided it would be less work in the long to bypass it. – Ben Voigt Feb 21 '13 at 23:50
  • Dammit. I had a feeling this was going to be an issue, as since I started with .NETs serial port library I spend half my time with workarounds. I hate to admit defeat because it means A LOT of work to move, but I will definitely start my research and see how it goes. Thanks for your time and patience. – tmwoods Feb 21 '13 at 23:53
  • Do you want to add that to your answer and I will mark it as correct? I wouldn't want people just reading the answer as it stands and getting the wrong impression (that happens waaaay too much on SO). Thanks again. – tmwoods Feb 21 '13 at 23:55
  • Also how do I add '@ben'? Every time I do it just vanishes when I add the comment... – tmwoods Feb 21 '13 at 23:56
  • @tmwoods: You're replying to my answer, so `@ben` isn't needed. On venom's answer, for example, it should work just fine. – Ben Voigt Feb 21 '13 at 23:57
0

serialPort1.Open();

is what is throwing the exception. Normally when you code, if an exception happens you do clean up of the connections.

As others mentioned, if you keep calling this same method, you'll keep getting exception unless things about the call change.

So understanding that, my suggestion would be that you look for other ways to open the serial port, other than the serialPort1.Open(); call. There may or may not be built in ways in C#. So you might have to be creative :)

James Oravec
  • 19,579
  • 27
  • 94
  • 160
  • I feel like there has to be a way to safely ignore known errors. This is a .NET bug that I am slowly learning is well-known but not fixed. Surely there must be a way to ignore these things. – tmwoods Feb 21 '13 at 23:33
  • 1
    If he's willing to give up the .NET `SerialPort` class, the Win32 API has serial port functions that work a lot better. And have more helpful error information. – Ben Voigt Feb 21 '13 at 23:45
  • @Ben Voigt, I agree, I think your suggestion is a good one :) – James Oravec Feb 21 '13 at 23:53
  • @tmwoods, sometimes buggy stuff gets release and later gets depreciate then replaced by better stuff. I would recommend following Ben's suggestion. – James Oravec Feb 21 '13 at 23:53
  • @VenomFangs: yeah, but.... the Win32 functions have been around since long before .NET. In fact, .NET SerialPort uses them (incorrectly). – Ben Voigt Feb 21 '13 at 23:54
  • @Ben Voigt, good call. Do you think MS will depreciate their mess up and replace it with something else or fix it in an upgrade in the future? – James Oravec Feb 22 '13 at 00:04
  • @VenomFangs: Well, I guess the WinRT API probably has something new for serial port access, presumably designed by the OS team (who have a clue about serial drivers), not the .NET team. But the .NET folks don't seem to be putting any more effort into desktop app development, all bug reports are getting closed using automated tools and all work seems to be toward Windows Store app development. – Ben Voigt Feb 22 '13 at 00:15
  • see http://blog.jerrynixon.com/2012/05/metro-answers-can-i-use-serial-port.html and http://social.msdn.microsoft.com/Forums/en-US/tailoringappsfordevices/thread/6bdaa46f-fa49-4854-a97b-81b003ef3495/ – Ben Voigt Feb 22 '13 at 00:17
0

From SerialPort.Open:

Only one open connection can exist per SerialPort object. The best practice for any application is to wait for some amount of time after calling the Close method before attempting to call the Open method, as the port may not be closed instantly.

And

The port is in an invalid state.

  • or -

An attempt to set the state of the underlying port failed. For example, the parameters passed from this SerialPort object were invalid.

I bet this is what is happening... your SerialPort was recently open and now you're trying to open it again before it's ready.

My advice is to write a loop, and sleep a bit between Opening attempts. Figure out how many times you're willing to try over how long of a period. break out of the loop when you succeed.

foreach(int i in Enumerable.Range(1, numberOfAttempts)
{
  try
  {
    serialPort1.Open();
    break;
  }
  catch(Exception ex)
  {
    //log attempt #i failed because of ex
  }
  Thread.Sleep(millisecondsToWait);
}
Amy B
  • 108,202
  • 21
  • 135
  • 185