Безопасное использование MemoryMappedFile - PullRequest
0 голосов
/ 12 апреля 2020

Новые функции, связанные с Span в. NET делают использование ввода-вывода с отображением в памяти намного более точным, и это также может быть очень безопасным, хотя MS еще не делает его надежным, и я не уверен если я вижу все подводные камни.

Первый облом в том, что MemoryMappedFile все еще дает мне только указатель на отображенную память, а не промежуток:

var mmf = MemoryMappedFile.CreateFromFile(name + ".mmf", FileMode.Create, name, length);
var mmv = mmf.CreateViewAccessor();
mmv.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);

Это само по себе требует использования о небезопасном ключевом слове и опции компилятора, заставляя меня думать.

Но по крайней мере я могу создать Span из этого как new Span<Byte>(ptr, length), и оттуда использовать его безопасно.

Там Тем не менее, по-прежнему необходимо приводить к пользовательским, неуправляемым типам структур, чтобы эффективно использовать память, отображаемую в IO. Поэтому я рассматриваю этот метод расширения для переинтерпретации приведений:

public static class SpanExtensions
{   
    public static unsafe Span<T> Cast<T>(this Span<Byte> bytes)
        where T : unmanaged
    {
        fixed (byte* ptr = &bytes.GetPinnableReference())
            return new Span<T>(ptr, bytes.Length / sizeof(T));
    }
}

Все эти небезопасные ключевые слова заставляют меня немного нервничать, и я хотел бы, чтобы кто-то в курсе подтвердил некоторые мои предположения:

  1. Нет части поверхности IO API с отображением в памяти, которую я мог бы использовать без ключевого слова unsafe и переключателя компилятора, если я хочу получить Span<T> для некоторого неуправляемого типа T.
  2. Указатель, полученный от AcquirePointer, уже закреплен (документация ничего об этом не говорит, но я предполагаю, что отображенная память находится вне ответственности G C).
  3. Мое приведенное выше расширение для литья безопасно, даже в случае, когда я использую его в течение Span с управляемой памятью (например, Byte[]), поскольку я ограничиваю возможность преобразования неструктурированными структурами, которые не могут содержать ссылок.

Правильно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...