Reputation: 33
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
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
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