6

I have an application talking to a USB-GPS. It’s working as a charm if nothing out of the ordinary happnes. But I have a big problem. If the USB gets pulled out, my program (some times) crashes. I have Try/Catch where I need them but this IOExeption doesn’t get caught. I just get "The device does not recognize the command" and the program stops. Here is the code that starts the port:

        public LatLongFromGPS(Form1 parent)
    {
        this.parent = parent;
        String port;
        this.SPort = new SerialPort(port, 4800);
        this.SPort.ReadTimeout = 500;
        this.SPort.DataReceived += new SerialDataReceivedEventHandler(dataReceived);
    }

    public bool checkIfPortsOpen()
    {
        return (this.SPort.IsOpen);
    }

    public void openPort()
    {
        try
        {
            if (!this.SPort.IsOpen)
            {
                this.SPort.Open();
            }
        }
        catch(Exception ex)
        {
            parent.LoggIt.WriteLogg("OPENPORT " + ex.ToString(), Logger.LoggType.Debug);
        }
    }

    public void dataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        try
        {
            if (SPort.IsOpen)
            {
                String GPGGAString;
                Thread.CurrentThread.Join(200);
                buffert = new char[this.SPort.BytesToRead];
                this.SPort.Read(buffert, 0, buffert.Length);
                GPGGAString = findStringFromGPS();
                if (GPGGAString != null)
                {
                    getLatitudefromString(GPGGAString);
                    getLongitudefromString(GPGGAString);
                    getTimeFromString(GPGGAString);
                    this.newData = true;
                }
            }
        }
        catch(Exception ex)
        {
            parent.LoggIt.WriteLogg("GPSERROR    " + ex.ToString(), Logger.LoggType.Debug);
        }
    }

Then I have this in a Timer to check the info

if (this.LatLong.newDataReceived())
   {
        //DOING STUFF
   }

if (!this.LatLong.checkIfPortsOpen())
       this.LatLong.openPort();

Anyone have any suggestions how to stop the crashes?

[EDIT] The stack:

at System.IO.Ports.InternalResources.WinIOError(Int32, System.String)

at System.IO.Ports.InternalResources.WinIOError()

at System.IO.Ports.SerialStream.Dispose(Boolean)

at System.IO.Ports.SerialStream.Finalize()
David Storey
  • 29,166
  • 6
  • 50
  • 60
Nick3
  • 639
  • 1
  • 14
  • 40
  • it sounds to me like the exception is happening on a worker thread; what is the `.StackTrace` of the exception that appears on screen? (probably in an ugly error box) – Marc Gravell Feb 19 '13 at 14:12
  • Is you error written to log by `parent.LoggIt.WriteLogg("GPSERROR "` line? – Artemix Feb 19 '13 at 14:12
  • Did you ever set `port` before using it? – John Saunders Feb 19 '13 at 14:17
  • I would attach the debugger and enable break on exceptions, so that you can pinpoint where things go wrong. `IOException` WILL be caught with a catch(Exception) so the problem does not lie in the `dataReceived` callback. – bas Feb 19 '13 at 14:17
  • No the debuger can't locate it. Just gets IOExeption, nothing like an "usual" crash. I added the stack in the main post! The Logger does not pick it up since the catch doesn't... – Nick3 Feb 19 '13 at 14:22
  • Looks like a dispose problem to me. Your `SerialPort` is being finalized and consequently disposed. As a result its `SerialStream` is also disposed. That's what happens in this stacktrace to me. is this the complete stacktrace? how can you tell it's an it's an `IOException`? – bas Feb 19 '13 at 14:34

2 Answers2

1

I'm not entirely sure if it applies here, but there are mechanisms to catch overall crashes at the appdomain level - http://msdn.microsoft.com/en-GB/library/system.appdomain.unhandledexception.aspx

(not the section on other events, e.g. ThreadException - these may need their own handlers depending on the situation)

NDJ
  • 5,189
  • 1
  • 18
  • 27
  • "catch" is perhaps over-stating it; you can *log* them if you're quick, but usually it is terminal at that stage and your process is about to die – Marc Gravell Feb 19 '13 at 14:11
0

Although not a best practice, top-level exception handling might solve your problem. See http://richnewman.wordpress.com/2007/04/07/top-level-exception-handling-in-windows-forms-applications-%E2%80%93-code-listing-1/ for an example.

bytefire
  • 4,156
  • 2
  • 27
  • 36