zsavas
zsavas

Reputation: 33

"activator.createinstance()" gives error when try to run

I was unable to solve the following error. I'll appreciate your help.

I have the following class:

public class GB
{
        private StreamReader sr;
        public GB()
        {
            sr = new StreamReader(new FileStream("C:\\temp.txt", FileMode.Open, FileAccess.ReadWrite));
        }
        public int MultiCall()
        {
            if (sr.ReadLine() == "test1")
                return 1;
            else
                return 0;
        }
    }

in my form, there is button with the following function;

void buttonClick()
{
  myAssembly = Assembly.LoadFrom(dllpath); // dllpath is the dll file for GB class
  myType = myAssembly .GetType("GB");
  myObject = Activator.CreateInstance(myType);

  myMethodInfo = myType .GetMethod("MultiCall");
  returnValue = myMethodInfo.Invoke(myObject, null);

  myObject = null;
}

Here is my question; When i click the button for the first time, Everything is OK. But when i click it again i get the following error;

The process cannot access the file 'C:\temp.txt' because it is being used by another process.

The object returned from activator.createinstance doesnot seem to be nulled after first call. Although i assign it to a null value by myObject = null i still get the same error. Any ideas?

thx.

Upvotes: 0

Views: 870

Answers (2)

OneFineDay
OneFineDay

Reputation: 9024

Store the value returned by the file then check it value in the MultiCall method. This way you file gets closed and disposed for you.

public class GB
{
    private string str;
    public GB()
    {
        using (var sr = new StreamReader(new FileStream("C:\\temp.txt", FileMode.Open, FileAccess.ReadWrite)))
        {
          str = sr.ReadToEnd();
        }

    }
    public int MultiCall()
    {
        if (str == "test1")
            return 1;
        else
            return 0;
    }
}

Upvotes: 0

Lukazoid
Lukazoid

Reputation: 19416

The constructor of GB opens a ReadWrite stream to the file, but then never closes it. The subsequent invocation of GB attempts to open the same file, but this obviously fails.

What you need to do is implement IDisposable on GB, which disposes of the StreamReader, e.g.:

public class GB : IDisposable
{
    private StreamReader sr;
    private bool _isDisposed;

    public GB()
    {
        sr = new StreamReader(new FileStream("C:\\temp.txt", FileMode.Open, FileAccess.ReadWrite));
    }
    public int MultiCall()
    {
        if (sr.ReadLine() == "test1")
            return 1;
        else
            return 0;
    }

    ~GB()
    {
        Dispose(false);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool isManaged)
    {
        if(_isDisposed)
            return;

        if(isManaged)
        {
            // Ensure we close the file stream
            sr.Dispose();
        }

        _isDisposed = true;
    }
}

Then dispose of your GB instance once you are done with it.

// Dispose of the GB instance (which closes the file stream)
var asDisposable = (IDisposable)myObject;
asDisposable.Dispose();

IDisposable exists for exactly this reason, to ensure unmanaged resources are successfully released.

Upvotes: 1

Related Questions