Objects disposed incorrectly


DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 2 of 2

Thread: Objects disposed incorrectly

Hybrid View

  1. #1
    Join Date
    Jul 2006
    Posts
    4

    Objects disposed incorrectly

    Objects appear to be disposed incorrectly.

    Application is compiled Visual Studio 2003 written in VB.NET.
    Same error occurs on 6 different clients with varying configurations.
    Client configurations range from P3-800MHz w/128 MB RAM running Win2K Pro SP4 to P4-1.6 GHz 1/1.0 GB RAM running WinXP Pro SP 2.
    All clients have .NET Framework 1.4322 installed; .NET Framework 2.0 NOT installed.
    Some, but not all, clients have MS Office 2003 installed.
    Two machines have Visual Studio .NET 2003 installed, the rest do not.

    When running executable on machines without VS .NET installed, error message is "Failed to load resources from resource file. Please check yuur setup." pops up. The application crashes after the message is acknowledged.

    When running executable on machines with VS .NET, JIT Debugger is activated and the message ultimately displayed is "An unhandled exception of type 'System.ExecutionEngineException' occurred in system.windows.forms.dll."

    Wben running in debug mode on machines with VS .NET, application executes as expected, throwing no errors at all.

    When progress logging to an output file is added, error trapping is enhanced and the application is recompiled and executed on a machine without Visual Studio, the error message changes to "Cannot access a disposed object." at the point where a custom local object should be accessed.

    A simplified description of the application is this:
    Custom class 'X' is defined that contains MS System.Security.Cryptography methods and is used to decrypt and encrypt data files. Class 'X' contains a Finalize destructor but does not include a Dispose method.

    Custom class 'CD' provides methods to handle data within the data files.

    Within a form:
    A module level 'CD' object is defined, instantiated on form load and destroyed on form closing.

    Method OpenFile is a function that creates an object of custom class 'X', decrypts an input file into a byte array, converts the byte array into the module CD object and returns a boolean indicating whether it was successful. Its error trapping assumes that all problems are due to use of an incorrect password. The code is roughly:
    Dim objectX as New X
    Dim b() As Byte = objectX.Decrypt(file)
    CD = Convert(b)
    Return <result>

    Method SaveFile is a sub that creates an object of custom class 'X', encrypts the module CD object and saves the result under a different file name. It catches and displays Exception errors. The code is roughly:
    Dim objectX as New X
    objectX.Encrypt(CD, file)

    The OpenFile and SaveFile class 'X' objects are completely independent of one another.
    In both methods, the code using the class 'X' object occurs in sequential lines exactly as shown above and is never used again.
    Each time either method is called, a fresh instance of the local class X object is created; there is no persistent data in the class 'X' object.
    Neither method explicitly destroys its class 'X' object. Rather, both methods depend on the garbase collector to recognize that the method has completed and to release the class 'X' object resources.

    This is the procedure for importing a new data file:
    Method ImportFile is called to process the input file.
    Method OpenFile is called to decrypt the input file into the module CD object, exiting and returning True if successful.
    Method SaveFile is called to encrypt the module CD object, saving the encrypted results as a new file if successful.
    Method OpenFile is called a second time, decrypting the new file, recreating the module CD object, exiting and returning True if successful.
    (OpenFile is called twice for a reason that's irrelevant to the problem.)
    Method ImportFile exits.

    The first OpenFile call always succeeds.
    The failure occurs during SaveFile at the objectX.Encrypt(CD, file) line but only when running as an executable, never when loaded into Visual Studio and running in debug mode.

    I tried explicitly destroying the method class 'X' objects by changing the code as follows:
    Dim objectX as New X
    <use objectX.method>
    objectX = Nothing
    This change had no effect, presumably because it's still dependent on the garbage collector cleaning up the resources.

    When running in debug mode with enhanced logging and error trapping, the log file looked like this:
    The first OpenFile call began and completed without error.
    The SaveFile call began. While the SaveFile Class X object was still encrypting the data, Class X Finalize log messages appeared, presumably generated as the garbage collector destroyed the OpenFile class X object. The SaveFile call completed without error and the output file appeared to be as expected.
    The second OpenFile call began. Class X Finalize log messages appeared while OpenFile was running, presumably cleaning up the SaveFile class X object.
    The second OpenFile call completed without error.
    After a short time, Class X Finalize log messages would appear again, this time cleaning up the class X object from the second OpenFile call.

    When running the executable with enhanced logging and error trapping, the log file looked like this:
    The first OpenFile call began and completed without error.
    The SaveFile call began. Somewhere in the middle, while encrypting the CD object, class X Finalize log messages appeared, presumably generated as the garbage collector destroyed the OpenFile class X object. At this point, the executable failed with the error message "Cannot access a disposed object" that appeared to be thrown because the SaveFile class X object had been destroyed. The output file was incomplete.
    As noted, the OpenFile and SaveFile class X objects are both method level and should not affect one another but it appears that's what happened.

    If the data file was very small, the error might not occur, probably because a small enough file could be completely processed before the class X Finalize method was invoked.

    My ultimate solution was this:
    Since the OpenFile and SaveFile methods never overlap their use of the class 'X' object, I moved it out to the module level.
    It is now declared at the module level, instantiated on form load and destroyed (set to Nothing) on form Closing.
    The OpenFile and SaveFile methods now simply use the module level class X object and my problem is resolved.

    The class X object is overscoped since it is used only inside 2 independent methods but that's not a horrible issue.

    What is a problem is why the original code should cause a problem.
    I can only guess, but it looks like one of two things is happening:
    1. The system knows that OpenFile has finished with its class X object storage and reuses all or part of the same storage for the SaveFile object.
    When the garbage collector cleans up the OpenFile resources, it destroys the storage that SaveFile's class X object is now using.
    2. There are 2 separate class X objects using different storage locations but the garbage collector somehow gets "confused" and destroys the SaveFile class X object that it should leave alone.

    Either way, it looks like some sort of bug with the garbage collector.

    Any thoughts?

  2. #2
    Join Date
    Jul 2006
    Posts
    4

    Problem resolved

    There were several issues.

    First, the problem was not a Garbage Collector issue after all. It was actually an out of memory exception but the original error trapping wasn't handling errors adequately and caused the problem to be manifested as an attempt to access a disposed object.

    Second, in the original code, there were some rather large method level objects that were not explicitly disposed, a Crypt object was being declared inside 3 different class module methods, a couple of other objects that had the potential to become quite large were declared inside a loop(?!) and the Finalize method was called at the beginning of the Finalize sub. Explicitly disposing method level objects and moving the Crypt object to the module level, the object declarations outside the loop and the Finalize method call to the end of the Finalize Sub eliminated the "object disposed" error and lowered memory usage substantially but did not resolve an out of memory error that still occurred on some machines.

    Second, it turned out that the systems that were throwing out of memory errors had .NET Framework 1.1 Redistributable installed but not the .NET Framework 1.1 SP1, which was installed on all machines that worked. Installing the missing .NET Framework 1.1 SP1 on the problem machines resolved the OOM error. (Note: I had been told that the problem machines had been updated but could not confirm myself because, as a developer in my environment, I do not have access to the problem machines, which are in a different domain and at a different physical location.)

Similar Threads

  1. Bug with Creation of Objects in SQL *Plus Worksheet
    By Michael Cole in forum Database
    Replies: 2
    Last Post: 04-02-2003, 03:06 PM
  2. Bug with Creation of Objects in SQL *Plus Worksheet
    By Michael Cole in forum oracle.general
    Replies: 0
    Last Post: 02-20-2003, 10:25 PM
  3. Pooling in n-tier architecture
    By Jeff Pipes in forum .NET
    Replies: 11
    Last Post: 05-15-2002, 10:17 AM
  4. Thin Objects for Better Performance
    By Dave Fleischman in forum Enterprise
    Replies: 3
    Last Post: 08-18-2000, 01:10 PM
  5. Components vs Objects
    By Oliver Lennon in forum Enterprise
    Replies: 3
    Last Post: 04-18-2000, 12:30 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center