Hi everybody

In an application I have, I had to start a word app. Because it took ages to load, I put it in the class constructor, but on exiting the app is not killed. I am trying to kill it by creating a destructor

~MyClass(){
        appWord.Quit();
}

but I need 3 args in the quit method. What to do?

Recommended Answers

All 7 Replies

~Methods are finalizers and not identical to destructors as you may be used to. You should implement the IDisposable interface on the class that encapsulates or uses the word document and clean up the unmanaged resource there. To ensure .Dispose() is called you should use the using() claused.

using (WordClass wc = new WordClass())
{
  wc.DoWork();
} //The object is disposed here which will clean up the word process if implemented properly.

The .NET Framework will call Dispose on IDisposable objects when they are out of scope and no longer referenced but it is slightly more expensive to calculate which objects it can dispose versus what objects it was explicitly told to dispose.

I am sorry to bother you again Sknake, but although I understand what you are saying, I have no idea how to implement it.

Where and how to use using?

And then

public partial class MyClass : IDisposable
    {
        public void Dispose()
        {
            appWord.Quit(ref filler, ref filler, ref filler);
        }
    }

or I have it totally wrong?

Thanks again

Please post the code for your class

It is 2500 lines long and it is done for my company I am afraid, so I cannot attach it. Anyway thanks.

No but you can make a slimmed down version of the code with just enough lines to reproduce the undesired behavior. I will give you an example of another class using IDisposable and how to call it ensuring unmanaged resources are freed/closed.

Equivelant to your 2500 lines:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;

namespace daniweb
{
  public class MyResource : IDisposable
  {
    // Pointer to an external unmanaged resource.
    private IntPtr handle;
    // Other managed resource this class uses.
    private Component component = new Component();
    // Track whether Dispose has been called.
    private bool disposed = false;

    public string ResourceName { get; set; }

    // The class constructor.
    public MyResource(IntPtr handle)
    {
      this.handle = handle;
    }

    // Implement IDisposable.
    // Do not make this method virtual.
    // A derived class should not be able to override this method.
    public void Dispose()
    {
      Dispose(true);
      // This object will be cleaned up by the Dispose method.
      // Therefore, you should call GC.SupressFinalize to
      // take this object off the finalization queue
      // and prevent finalization code for this object
      // from executing a second time.
      GC.SuppressFinalize(this);
    }

    // Dispose(bool disposing) executes in two distinct scenarios.
    // If disposing equals true, the method has been called directly
    // or indirectly by a user's code. Managed and unmanaged resources
    // can be disposed.
    // If disposing equals false, the method has been called by the
    // runtime from inside the finalizer and you should not reference
    // other objects. Only unmanaged resources can be disposed.
    private void Dispose(bool disposing)
    {
      // Check to see if Dispose has already been called.
      if (!this.disposed)
      {
        // If disposing equals true, dispose all managed
        // and unmanaged resources.
        if (disposing)
        {
          // Dispose managed resources.
          component.Dispose();
        }

        // Call the appropriate methods to clean up
        // unmanaged resources here.
        // If disposing is false,
        // only the following code is executed.
        CloseHandle(handle);
        handle = IntPtr.Zero;

        // Note disposing has been done.
        disposed = true;

      }
    }

    // Use interop to call the method necessary
    // to clean up the unmanaged resource.
    [System.Runtime.InteropServices.DllImport("Kernel32")]
    private extern static Boolean CloseHandle(IntPtr handle);

    // Use C# destructor syntax for finalization code.
    // This destructor will run only if the Dispose method
    // does not get called.
    // It gives your base class the opportunity to finalize.
    // Do not provide destructors in types derived from this class.
    ~MyResource()
    {
      // Do not re-create Dispose clean-up code here.
      // Calling Dispose(false) is optimal in terms of
      // readability and maintainability.
      Dispose(false);
    }
  }
}

Calling it:

private void button8_Click(object sender, EventArgs e)
    {
      using (MyResource res = new MyResource(IntPtr.Zero))
      {
        //res.DoStuff();
      } //the dispose is called here
    }

Now you have an example of disposing and finalizing without disclosing any of your code.

Tried it and worked. Thank you very much Sknake and sorry for being such a pain

You're welcome i just get irked when people don't want to post code when i'm trying to help them :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.