This is how to implement dispose pattern to file reading in C#:
using System;
using System.IO;
class BaseResource: IDisposable
{
// Track whether Dispose has been called.
private bool disposed = false;
// The unmanaged resource wrapper object
private FileStream file;
// Class constructor
public BaseResource(String fileName)
{
Console.WriteLine("BaseResource constructor allocates unmanaged resource wrapper");
file = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
}
// Implement IDisposable
public void Dispose()
{
// Check to see if Dispose has already been called.
if (!disposed)
{
Console.WriteLine("Dispose pattern releases unmanaged resource wrapper's resource");
file.Close();
disposed = true;
}
}
public void Close()
{
Dispose();
}
public void DoSomething()
{
Console.WriteLine("In BaseResource.DoSomething");
}
}
Also in some ways, calling Dispose() or Close() multiple times is completely harmless. However, this implementation of the dispose pattern is not thread-safe. Another thread could start disposing the object after the unmanaged resource wrappers are disposed, but before the internal disposed field is set to true. If you were writing a class for use in a multi-threaded application and were ensuring the class was thread-safe then this is how you would do it for the Dispose() method. The following modification to Dispose() remedies this by locking the object for the method's duration to prevent any other threads calling Dispose() at the same time.
Here is the C# rewrite:
// Implement IDisposable
public void Dispose()
{
lock(this)
{
// Check to see if Dispose has already been called.
if (!disposed)
{
Console.WriteLine("Dispose pattern releases unmanaged resource wrapper's resource");
file.Close();
disposed = true;
}
}
}
Source: http://edn.embarcadero.com/article/29365
using System;
using System.IO;
class BaseResource: IDisposable
{
// Track whether Dispose has been called.
private bool disposed = false;
// The unmanaged resource wrapper object
private FileStream file;
// Class constructor
public BaseResource(String fileName)
{
Console.WriteLine("BaseResource constructor allocates unmanaged resource wrapper");
file = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
}
// Implement IDisposable
public void Dispose()
{
// Check to see if Dispose has already been called.
if (!disposed)
{
Console.WriteLine("Dispose pattern releases unmanaged resource wrapper's resource");
file.Close();
disposed = true;
}
}
public void Close()
{
Dispose();
}
public void DoSomething()
{
Console.WriteLine("In BaseResource.DoSomething");
}
}
Also in some ways, calling Dispose() or Close() multiple times is completely harmless. However, this implementation of the dispose pattern is not thread-safe. Another thread could start disposing the object after the unmanaged resource wrappers are disposed, but before the internal disposed field is set to true. If you were writing a class for use in a multi-threaded application and were ensuring the class was thread-safe then this is how you would do it for the Dispose() method. The following modification to Dispose() remedies this by locking the object for the method's duration to prevent any other threads calling Dispose() at the same time.
Here is the C# rewrite:
// Implement IDisposable
public void Dispose()
{
lock(this)
{
// Check to see if Dispose has already been called.
if (!disposed)
{
Console.WriteLine("Dispose pattern releases unmanaged resource wrapper's resource");
file.Close();
disposed = true;
}
}
}
Source: http://edn.embarcadero.com/article/29365
Комментарии
Отправить комментарий