+ Reply to Thread
Page 1 of 2 1 2 LastLast
Results 1 to 10 of 13

Thread: Cannot Access Disposed Object. *FORM ERROR*

  1. #1
    Element6 is offline VB.NET Forum Enthusiast Element6 is on a distinguished programming path ahead
    .NET Framework
    .NET 3.0
    Join Date
    Feb 2010
    Age
    35
    Posts
    85
    Reputation
    9

    Default Cannot Access Disposed Object. *FORM ERROR*

    This is just an FYI; because I got so many hits on google for it.

    I got the "infamous" 'Cannot Access Disposed Object.' error when I was attempting to open a form again after I had closed it.

    The fix (even though it's annoying), is easy enough; but again it's managed code problems and weirdisms I still haven't changed my opinion that I won't be using MS .NET after this when I get my development box back to normal. BUT anyway the solution is self explanitory and very easy (and somewhat obvious)

    Code:
            
            Dim SomeForm = New Form1
            If SomeForm.IsDisposed Then Return
            SomeForm.Show()
    I think what happens (without indepth knowledge of how 3.5 managed code is working.) The "variable" name declaration is associated to some pointer; and the pointer is either A not being used as the lookup and the Variable Name is, or B the collection is overriding the active declaration and not updating the Garbage Collection.

    I know this because this code doesn't work.

    Code:
            
            Dim SomeForm = New Form1
            SomeForm.Show()
    When it gets to
    Code:
            SomeForm.Show()
    the Application hickups with a very nice message, after you close the form down and try to reopen it, that says :
    Cannot access Disposed object.
    So, my thought is that the "IsDisposed" property runs some sort of function to determine the Garbage Collection state and does a collection, or updates the request for the collection to be done.

    Either way, an FYI and heads up for a rather annoying little problem.

  2. #2
    jmcilhinney's Avatar
    jmcilhinney is offline VB.NET Forum Moderator jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute
    .NET Framework
    .NET 3.5 (VS 2008)
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Age
    41
    Posts
    6,736
    Reputation
    653

    Default

    The OS assigns a handle to each window it displays. When you close a .NET Windows Form you dispose it, which releases that handle back to the OS. The form still exists in memory so you can still access it but you can't show it again because it has no handle. If you want to show another form you have to create another form. That's the way it is and that's the way it's supposed to be. Noone is keeping this fact a secret so you might want to do a bit more research.

  3. #3
    Element6 is offline VB.NET Forum Enthusiast Element6 is on a distinguished programming path ahead
    .NET Framework
    .NET 3.0
    Join Date
    Feb 2010
    Age
    35
    Posts
    85
    Reputation
    9

    Default

    I knew that it was associated; and I knew there was a pointer.

    Why do I have to query to see if the thing is disposed; It's not like I can "undispose" an object that has released it's Pointer / Handle; so why should I have to query if it?

    This is constant in the framework; the Dim New should have been enough to allow the New "Handle" / Pointer and Override the Assignment; in cases where code would step on each other; it should override it still - and float an ambigious Handle and make it into a broken link. Honestly, it's much easier to handle broken associations then it is to manage associations on the fly.

    Broken Associations can be identified by the "managed resources"; what does the program care. I don't like the fact that .NET tries to override how to do programming from a managed state; that is a seperate issue and should be handled as such.

    Seriously, if people write bad code - then let it be bad code; .NET is good in the sense that it tries to make everyone that develops a good programmer but in the end it just dumbs down the masses and makes for sloppy business. Just my opinion.

    Thank you for your input and yes I "should" do more research - but sometimes when you attack a problem blindly; you get a much better understanding.

    As usual, you always have good comments. Not being conflictive, just an old salty developer. As usual for RAD development Microsoft has done well, but as for "technically"; I think they are moving towards the Apple philospophy - and I won't be with them.

  4. #4
    JuggaloBrotha's Avatar
    JuggaloBrotha is offline VB.NET Forum Moderator JuggaloBrotha VB.NET gold medalist JuggaloBrotha VB.NET gold medalist JuggaloBrotha VB.NET gold medalist JuggaloBrotha VB.NET gold medalist JuggaloBrotha VB.NET gold medalist JuggaloBrotha VB.NET gold medalist JuggaloBrotha VB.NET gold medalist JuggaloBrotha VB.NET gold medalist JuggaloBrotha VB.NET gold medalist JuggaloBrotha VB.NET gold medalist JuggaloBrotha VB.NET gold medalist
    .NET Framework
    .NET 2.0
    Join Date
    Jun 2004
    Location
    Lansing, MI; USA
    Age
    26
    Posts
    3,897
    Reputation
    524

    Default

    This work consistently:
    Code:
    Public Class Form1
        Private SomeForm As SomeForm
    
        Private Sub Button1_Click (...) Handles Button1.Click
            m_SomeForm = New SomeForm
            With m_SomeForm
                If .ShowDialog(Me) <> System.Windows.Forms.DialogResult.Cancel Then
                    'Some code
                End If
                .Dispose()
            End With
        End Sub
    
    End Class
    The only other thing that I may have to do outside of this type of structure is checking that it's not nothing, like:
    Code:
    If m_SomeForm IsNot Nothing Then
    or
    Code:
    If m_SomeForm Is Nothing Then
    Currently using: VS 2005 & 2008 Pro w/sp1 & VS 2010 Ultimate on Win7 Ultimate x64.


    There are 3 kinds of people in the world: Those who can count and those who can't.
    4 out of 3 people have trouble with fractions.

    Windows has a 64 bit GUI for a set of 32 bit extensions on a 16 bit shell for an 8 bit OS using a 4 bit kernel made by a 2 bit company that can't stand 1 bit of competition.

  5. #5
    Element6 is offline VB.NET Forum Enthusiast Element6 is on a distinguished programming path ahead
    .NET Framework
    .NET 3.0
    Join Date
    Feb 2010
    Age
    35
    Posts
    85
    Reputation
    9

    Default

    The problem occurs outside the Called Class; as part of the caller, not a part of the class itself. It's a matter of opening and reopening the form multiple times.

    ClassA calls ClassB with .Show() and maintains the reference.

    ClassA after the reference has been collapsed (Disposed) cannot define ClassB because it's in Disposed mode and the "Handle/Pointer" is broken because there is no data related, so it is a state problem, and shows that .NET is also in error about being stateless code, which it promotes in the webside development. So to clear the state, you have to run a garbage collection to clear the managed array information.

    What MicroSoft ought to do is manage the list with the IsDisposed flag and when it's set to true; run an automatic removal from the list or collection immediately. It's an error in logic despite what the .NET guys tell you. It is incomplete logic.

    Something like : ' Clean coding not that complicated jazz



    Code:
    Private lastStartIndex as Integer = 0
    
    Public Sub WhileDisposing(startIndex as Integer, optional indexWorkLength as Integer = 10) 
        Dim countRowOffset as Integer = 0
        Dim localCopyArray as Array = Nothing
        Dim removeIndexes() as Integer = Nothing
    
        If Not WhateverTheManagedIndexArrayIs Is Nothing Then
    
           localCopyArray = WhateverTheManagedIndexArrayIs.Clone()
    
           For x = startIndex to startIndex + indexWorkLength
              If x < localCopyArray.length Then
                 If WhateverTheManagedIndexArrayIs(x).IsDisposed Then
                    AddToArray(removeIndexes, x)
                 End If
              End If
           Next
    
           If Not removeIndexes Is Nothing Then countRowOffset = removeIndexes.Length 
           For x = 0 to removeIndexes.Length
                    RemoveThisIndexFromArray(WhateverTheManagedIndexArrayIs, removeIndexes(x))
           Next
    
          lastStartIndex = startIndex + indexWorkLength - countRowOffset 
       End If
    End Sub
    Force WhileDisposing state as a part of disposing. Very simple very clean and guarenteed.

    It's a managed resources issue; because they want to keep variables in scope rather then declaring them new each time; so all of a sudden they have overhead because they created the overhead in the sense of wanting to know what variables are where and what they are/were doing.
    Last edited by Element6; 03-20-2010 at 2:47 PM.

  6. #6
    jmcilhinney's Avatar
    jmcilhinney is offline VB.NET Forum Moderator jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute
    .NET Framework
    .NET 3.5 (VS 2008)
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Age
    41
    Posts
    6,736
    Reputation
    653

    Default

    Microsoft ought not to do anything. Things are fine as they are. You're just trying to turn something that's very simple into something that's very difficult. The only time I've ever needed to use the IsDisposed property is if I want singleton-style behaviour from a form. It's very, very simple: if you call Show on a form and then call Close, the form is disposed, i.e. its handle is released. The one and only reason you would need to test IsDisposed on a form is if you want to call Show on it and you're not sure if Close has already been called. In that case, the code is very, very simple:
    Code:
    If myForm Is Nothing OrElse myForm.IsDisposed Then
        myForm = New SomeForm
    End If
    
    myForm.Show()
    myForm.Activate()
    That is all you need, so why make a big song and dance about it? That code will focus an existing form if there is one or create and display a new one if there isn't. Simple; logical; easy.

  7. #7
    Element6 is offline VB.NET Forum Enthusiast Element6 is on a distinguished programming path ahead
    .NET Framework
    .NET 3.0
    Join Date
    Feb 2010
    Age
    35
    Posts
    85
    Reputation
    9

    Default

    Thats what I thought too.

    I received the error in a non - singleton state; it was being used in a conventional way in the form of a usercontrol calling the "form.show" method it was allowed for multiple form opens I had no restrictions.

    The reason the error occured is because of how I handle back processes during the idle state; it's a tweek to maximize performance in coding. Instead of using forced user button controls for everything I setup a handler in the background that runs during an idle phase of the application; this does basic background work such as repaints, and updates to form variables and such; so therefore object states become an issue, and I manage the states of the objects.

    Its a superior way of doing development and usually replaces your "For" and "Do while" loops because it's easier to control the application levels according to the user need. This is what the "real programmers and software engineers" do to make very large applications with lots of data be useful instead of waiting for 3 hrs for the application form to load so that customers are happy with performance over time.

    Anyway. As a result this error occurs in a form of stepping on the object while it's attempting to dispose; instead of the object just disposing. I don't understand why there is a need for a IsDisposing property at all. Why isn't it just gone as I said it's not like I can "UnDispose" the object. This is not a valid state of an object. What does Microsoft consider everything a flag variable and you just "flag" something to be comitted or deleted?

    If that was the case then timing functions will be out of the picture, because there is no "real-time" updating; so it gets down to the nitty gritty of handling the object state; is it predictable; and thats what the engineers do. Predict states and handle them.

    How do you ask an object that is supposed to be nullified if it exists? THE WHOLE PREMISE MAKES NO SENSE.

    In simple english that is like asking an orange that isn't there if it's been eaten.

    So yes, I am very sorry if you don't like the statement, but Microsoft really needs to rethink this because it's another ERROR in their logic and no worries we all do it; so they need the feedback to see it from the logical point of view that is different then their "elitist" view of the universe.

    Believe you me, I know I've been coding for 22 years and been working on Microsoft Platforms for years; they do the same things over and over again. Their major issue isn't that the product isn't good; it's that they aren't paying attention to details; and something like "IsDisposing" can easily be exploited to cause avoidable application and system failures.

    The real engineers have to worry about stuff like; if I have 30 million dollars worth of product going through this thing and then suddenly some hacker does an IsDisposed query look up that somehow fails the application and I lose a 10 million dollar transaction CAN I RECOVER IT?

    So please, less ego, and take what I say as a constructive critique.

  8. #8
    jmcilhinney's Avatar
    jmcilhinney is offline VB.NET Forum Moderator jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute
    .NET Framework
    .NET 3.5 (VS 2008)
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Age
    41
    Posts
    6,736
    Reputation
    653

    Default

    There is no IsDisposing property. There's an IsDisposed property. In the case of a control, the IsDisposed property tells you specifically whether the object has released its Window handle back to the OS or not. It says NOTHING about whether or not the object still exists. As with all managed objects, it exists in memory until the GC chooses to clean it up. In practical terms, the object exists as long as you have a reference to it.

    If it was displayed by calling its Show method, a form is disposed when you call its Close method. Why would it cease to exist at that point? Just because you've closed it doesn't mean that you don't want to use it. It just means that you don't want to display it.

    I take what you say as being as constructive as it was regarding generic objects. You are trying to force .NET to work the way you think it should. The way forms work with regards to disposal is fine as it is. Other than yourself, I'm not aware of anyone who has an issue with it. It certainly could work another way and that might be just as legitimate, but there's nothing illegitimate about the way it works now. I would suggest that you get a fuller understanding of how something works before suggesting that it should work differently.

  9. #9
    Element6 is offline VB.NET Forum Enthusiast Element6 is on a distinguished programming path ahead
    .NET Framework
    .NET 3.0
    Join Date
    Feb 2010
    Age
    35
    Posts
    85
    Reputation
    9

    Default

    Code:
    If myForm Is Nothing Or Else myForm.IsDisposed Then
        myForm = New SomeForm
    End If
    
    myForm.Show()
    myForm.Activate()
    One of us is not communicating well; because I just read what you said like 10 times to make sure.

    There's an IsDisposed property. In the case of a control, the IsDisposed property tells you specifically whether the object has released its Window handle back to the OS or not. It says NOTHING about whether or not the object still exists.
    If you look at your code for comparisson; you just said something that is contradictive to what you wrote in code. the ".IsDisposed" property (I mistyped when I said IsDisposing) is asssociated (most likely derived from an inheritable class) therefore it is very specific to asking the "object" if it exists in this case the object should always be set to IsDisposed to "False"; because it was created within the event for the first time in every instance the event "click" is invoked.

    It only works repeatedly when I check the "IsDisposed" property. Which should just be a variable lookup, apparently it does underline code that forces current managed stated information; that allows the form to load if it was already loaded once if I did not use the IsDisposed property it would not allow the form to load.

    I'm not argueing to argue; I am saying very clearly it is an incorrect placement. I should not have to view an objects property that has just clearly been created; to see if it is disposed; because obviously it wouldn't be; therefore it is a problem with managed code - because the old reference still manages that the old variable is active and disposed; unless I force it to view the new one. The logic is incorrect, and the placement is incorrect in this case and it's a very normal routine case.

    Instead the old reference is no longer valid in this case; the object has been rendered mute because the event "click" exited and so the local variable is no longer in scope.

    When I initiate a new "click" event; it should reinitalize the variable to the new form declaration and this is EXACTLY what it DOES NOT DO. How is the localized variable still in scope after the function is executed? I know your not saying that there is no special handling between local and global variables. The variable IS NEW; so my questions which is stll relevant is why do I have to check the IsDisposed of an object that obviously isn't? and why IsDisposed visible at application level when you'll never view it? It makes no sense; only at System Levels and that is beyond the scope of a simple "Click" event and my initial statement so consider it a subtle pointing of another problem.

    The first question I want answered because that is illogical.

  10. #10
    jmcilhinney's Avatar
    jmcilhinney is offline VB.NET Forum Moderator jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute jmcilhinney has a reputation beyond repute
    .NET Framework
    .NET 3.5 (VS 2008)
    Join Date
    Aug 2004
    Location
    Sydney, Australia
    Age
    41
    Posts
    6,736
    Reputation
    653

    Default

    As I've never seen or heard of a form that has just been created reporting itself as being disposed, I can only assume that the issue lies somewhere in your code. Without seeing more of that code and/or a more detailed explanation of what it does and why, I couldn't confirm or deny that. From what you've shown, there's no reason that that code should behave as you've described. If it was some fault with managed code then everyone would see the same issue. Either you're doing something very out of the ordinary or there is something specifically wrong with your system.

+ Reply to Thread
Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

     

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts