none
C# Safe handle has been closed

    Question

  • I'm getting "Safe handle has been closed" and "ObjectDisposedException was unhandled" as one error.
    I subclass System.Windows.Forms.IMessageFilter in order to catch the pressing of function keys on the keyboard. 

    I also have this.tbInput.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.misc_KeyPress);
    for catching Enter and Escape keys in a particular text box.

    I also have SQL reads:

    SqlConnection conn;
    conn = new SqlConnection(connectString);
    conn.Open();
    SqlCommand cmd = new SqlCommand(sql, POSregister.conn);
    rdr = cmd.ExecuteReader();

    while (rdr.Read())
    {  
    .
    .
    .

    The error is very intermittent.  I'm not sure but I think it might have something to do with the
    subclassing of IMessageFilter to catch pressing of F-Keys. 

    Thank you very much in advance!
    Thursday, March 06, 2008 4:24 PM

Answers

  • Exceptions should only be caught when you know what is causing them, and also when you know how to deal with the exception, otherwise you should never catch them, specially in development time as Visual Studio has good ways of giving you information on what is the problem you are having. Visual Studio debugger can give many hints as current variable values at the time of exception, stack trace, inner exception and many mor useful tips to help you solve your problem. I don't think that is a keyPress issue, subclassing implementing IMessageFilter is not a bad Idea, in fact it is very handy sometimes, you just need to make sure ou are doing it right. On your message filter for instance, you shouldn't do this:

     

    Code Snippet

    this.notification(null, null);

     

     

    instead, do this:

     

    Code Snippet

    this.notification(this, EventArgs.Empty);

     

     

    Regards,

    Fábio

    Monday, March 10, 2008 12:04 PM
  • Through a lot of trial and error I may have found a solution.  I have an output device that may be hooked up to the serial port.  After opening and writting to this output device I wasn't closing it.  I don't understand why that causes so much trouble but I hope it's fixed.

    Thank you all very much,
    lincolnkendal
    Thursday, March 13, 2008 2:28 PM

All replies

  • Where exactly are you getting the exception?

     

    Thursday, March 06, 2008 5:04 PM
  • It seems to be happening when I'm typing into the textbox having the KeyPressEvent trapping.
    I just wrapped a try catch block around the event handler code but the error is happening somewhere else. 

    I got:

    System.ObjectDisposedException was unhandled
      Message="Safe handle has been closed"
      Source="System"
      ObjectName=""
      StackTrace:
           at Microsoft.Win32.UnsafeNativeMethods.GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped* lpOverlapped, Int32& lpNumberOfBytesTransferred, Boolean bWait)
           at System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent()
           at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
           at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
           at System.Threading.ThreadHelper.ThreadStart()
    ------------------
    Shouldn't the call stack tell me where in may code the thing crashed?  The call stack shows:

       at Microsoft.Win32.UnsafeNativeMethods.GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped* lpOverlapped, Int32& lpNumberOfBytesTransferred, Boolean bWait)
       at System.IO.Ports.SerialStream.EventLoopRunner.WaitForCommEvent()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
    ------------------
    My code for handling function keys is:

     

            public frmMain()

            {

                InitializeComponent();

     

                myF_KeyFilter = new F_KeyMessageFilter(new System.EventHandler(F_Key_Pressed));

                Application.AddMessageFilter(myF_KeyFilter);

            }

            //***********************************************************

            private void F_Key_Pressed(object sender, EventArgs e)

            {

                try

                {

                    processInput();

                }

                catch (Exception ex)

                {

                    MessageBox.Show("in F_Key_Pressed have " + ex.Message);

                }

            }

            //***********************************************************

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.Windows.Forms;

    using System.Diagnostics;

    using System.Runtime.InteropServices;

     

    namespace SOA_Client

    {

        class F_KeyMessageFilter : System.Windows.Forms.IMessageFilter

        {

            private const int WM_KEYDOWN = 0x0100;

            private const int WM_SYSKEYDOWN = 0x0104;

     

            private const int VK_F1 = 0x70;

            private const int VK_F2 = 0x71;

            private const int VK_F3 = 0x72;

            private const int VK_F4 = 0x73;

            private const int VK_F5 = 0x74;

            private const int VK_F6 = 0x75;

            private const int VK_F7 = 0x76;

            private const int VK_F8 = 0x77;

            private const int VK_F9 = 0x78;

            private const int VK_F10 = 0x79;

            private const int VK_F11 = 0x7A;

            private const int VK_F12 = 0x7B;

     

     

            private EventHandler notification = null;

     

            public F_KeyMessageFilter(System.EventHandler notification)

            {

                this.notification = notification;

            }

     

            public bool PreFilterMessage(ref System.Windows.Forms.Message m)

            {

                try

                {

                    if ((m.Msg == WM_KEYDOWN) && (m.WParam.ToInt32() == VK_F1))

                    {

                        frmMain.textInput = "F1,";

                        frmMain.keyType = "F1";

                        if (this.notification != null)

                        {

                            this.notification(null, null);

                        }

                        return true;

                    }

    .

    .

    .

                    if ((m.Msg == WM_KEYDOWN) && (m.WParam.ToInt32() == VK_F12))

                    {

                        frmMain.textInput = "F12,";

                        frmMain.keyType = "F12";

                        if (this.notification != null)

                        {

                            this.notification(null, null);

                        }

                        return true;

                    }

                }

                catch (Exception ex)

                {

                    MessageBox.Show(ex.Message);

                }

                return false;

            }

        }

    }


    Thursday, March 06, 2008 9:06 PM
  • That is weird indeed, are you sure this is all your stack trace shows? The stack trace should walk all the way up the keyPress event handler, but maybe in this case as you are using a message filter in your code, the problem might reside there. But the stack trace seems to point to a threading problem, maybe a cross-thread exception? Are you using different threads to do different tasks? It seems that a one thread is releasing an object, and this object is beeing accessed by another thread, but it no longer exists.

     

    Could you tell in which line, the debugger points the exception? Remove the try block and check it.

    Is it on processInput() method (you said it was happening somewhere else)? Usually the Visual Studio debugger points the exception exactly where it happened (along with stack trace). And if the exception is in fact in processInput() method what is the implementation of this method.

     

    Another thing I noticed is that you have "SOA_Client" namespace. Is it a SOA app? This might explain the stack trace exception. As this is an IO excpetion, what is happening is that a SafeFileHandle is created (maybe used to connect to the service) and then this SafeFileHandle is closed/released and then you try to comunicate with the service again, but the SafeFileHandle is no longer available.

     

    These are just a few thoughts I had, maybe it is something else. If anyone has more ideas, it would be helpful.

    Regards,

    Fábio

    Friday, March 07, 2008 12:09 PM
  • Truly Weird.  It is so unpredictable that I am beginning to suspect a timing problem.  The application does have code to call on a web service but it dies before getting that far.  It has even died in the middle of drawing a row on it's datagridview.  It usually dies some time after I press enter on a text box.  Since I am catching keyPress I thought it might make a difference to type slow but I get the error going slow or fast.

    The call stack is what I see from the default exception handling.  I'm learning how to see a better call stack for next time I have a crash.  I've added quite a few try catch blocks to my code but haven't hit it yet.  Is it a bad idea to catch keypress events and also subclassing System.Windows.Forms.IMessageFilter to catch the pressing of function keys?  We are running .NET 2.0.
    Friday, March 07, 2008 8:50 PM
  • Exceptions should only be caught when you know what is causing them, and also when you know how to deal with the exception, otherwise you should never catch them, specially in development time as Visual Studio has good ways of giving you information on what is the problem you are having. Visual Studio debugger can give many hints as current variable values at the time of exception, stack trace, inner exception and many mor useful tips to help you solve your problem. I don't think that is a keyPress issue, subclassing implementing IMessageFilter is not a bad Idea, in fact it is very handy sometimes, you just need to make sure ou are doing it right. On your message filter for instance, you shouldn't do this:

     

    Code Snippet

    this.notification(null, null);

     

     

    instead, do this:

     

    Code Snippet

    this.notification(this, EventArgs.Empty);

     

     

    Regards,

    Fábio

    Monday, March 10, 2008 12:04 PM
  • Through a lot of trial and error I may have found a solution.  I have an output device that may be hooked up to the serial port.  After opening and writting to this output device I wasn't closing it.  I don't understand why that causes so much trouble but I hope it's fixed.

    Thank you all very much,
    lincolnkendal
    Thursday, March 13, 2008 2:28 PM