public void Close() #endif { if (!isOpen) { return; } bool shouldCloseConnection = (commandBehavior & CommandBehavior.CloseConnection) != 0; CommandBehavior originalBehavior = commandBehavior; // clear all remaining resultsets try { // Temporarily change to Default behavior to allow NextResult to finish properly. if (!originalBehavior.Equals(CommandBehavior.SchemaOnly)) { commandBehavior = CommandBehavior.Default; } while (NextResult()) { } } catch (MyCatException ex) { // Ignore aborted queries if (!ex.IsQueryAborted) { // ignore IO exceptions. // We are closing or disposing reader, and do not // want exception to be propagated to used. If socket is // is closed on the server side, next query will run into // IO exception. If reader is closed by GC, we also would // like to avoid any exception here. bool isIOException = false; for (Exception exception = ex; exception != null; exception = exception.InnerException) { if (exception is System.IO.IOException) { isIOException = true; break; } } if (!isIOException) { // Ordinary exception (neither IO nor query aborted) throw; } } } catch (System.IO.IOException) { // eat, on the same reason we eat IO exceptions wrapped into // MyCatExceptions reasons, described above. } finally { // always ensure internal reader is null (Bug #55558) connection.Reader = null; commandBehavior = originalBehavior; } // we now give the command a chance to terminate. In the case of // stored procedures it needs to update out and inout parameters command.Close(this); commandBehavior = CommandBehavior.Default; if (this.command.Canceled && connection.driver.Version.isAtLeast(5, 1, 0)) { // Issue dummy command to clear kill flag ClearKillFlag(); } if (shouldCloseConnection) { connection.Close(); } command = null; connection.IsInUse = false; connection = null; isOpen = false; }