简体   繁体   中英

Prevent memory leaks on reinitialise

I have a class that can open memory mapped files, read and write to it :

public class Memory
{
    protected bool _lock;
    protected Mutex _locker;
    protected MemoryMappedFile _descriptor;
    protected MemoryMappedViewAccessor _accessor;

    public void Open(string name, int size)
    {
        _descriptor = MemoryMappedFile.CreateOrOpen(name, size);
        _accessor = _descriptor.CreateViewAccessor(0, size, MemoryMappedFileAccess.ReadWrite);
        _locker = new Mutex(true, Guid.NewGuid().ToString("N"), out _lock);
    }

    public void Close()
    {
        _accessor.Dispose();
        _descriptor.Dispose();
        _locker.Close();
    }

    public Byte[] Read(int count, int index = 0, int position = 0)
    {
        Byte[] bytes = new Byte[count];
        _accessor.ReadArray<Byte>(position, bytes, index, count);
        return bytes;
    }

    public void Write(Byte[] data, int count, int index = 0, int position = 0)
    {
        _locker.WaitOne();
        _accessor.WriteArray<Byte>(position, data, index, count);
        _locker.ReleaseMutex();
    }

Usually I use it this way :

var data = new byte[5];
var m = new Memory();
m.Open("demo", sizeof(data));
m.Write(data, 5);
m.Close();

I would like to implement some kind of lazy loading for opening and want to open file only when I am ready to write there something, eg :

    public void Write(string name, Byte[] data, int count, int index = 0, int position = 0)
    {
        _locker.WaitOne();
        Open(name, sizeof(byte) * count); // Now I don't need to call Open() before the write
        _accessor.WriteArray<Byte>(position, data, index, count);
        _locker.ReleaseMutex();
    }

Question : when I call "Write" method several times (in a loop) it will cause member variables (like _locker) to reinitialise and I would like to know - is it safe to do it this way, can it cause memory leaks or unpredictable behavior with mutex?

If you open in the write method using a lock, it's safe to close before you release the mutex.

When you are dealing with unmanaged resources and disposable object, it's always better to implement IDispose interface correctly. Here is some more information .

Then you can initialse Memory instance in a using clause

using (var m = new Memory())
{
// Your read write
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM