Проблема с объемом памяти. Есть ли другой класс потока, такой как поток памяти, а не трибутарный? - PullRequest
0 голосов
/ 12 ноября 2018

Я пытаюсь сериализовать большие данные.Я получаю ошибку OutOfMemoryException при сериализации данных.Я сделал некоторые исследования.Я нашел некоторую информацию, что сказано, что есть ошибка о MemoryStream.Потому что поток памяти поддерживает размер данных 2 ГБ.Он имеет емкость как целое число.Я обнаружил, что вместо потока памяти можно использовать другой класс.Это называется MemoryTributary.Я попробовал этот класс.Но это дало мне действительно плохую производительность.Могу ли я найти основу или другую вещь, как поток памяти для больших данных?

Я хотел бы поделиться тем, что я сделал в ближайшее время:


  • Получить данные из SQLServer
  • Преобразовать данные в структуру
  • СериализацияДанные
  • Сжатие данных с использованием алгоритма LZ4
  • Загрузка данных в Azure

  • Получение данных из Azure
  • Распаковка данныхС помощью алгоритма LZ4
  • Десериализация данных
  • Использование данных для работы

У меня есть несколько кодов, как показано ниже:

    public static Stream ConvertObjectToStream<T>(T obj)
    {
        if (obj == null) return null;
        var boisSerializer = new BoisSerializer();
        try
        {
            var mem = new MemoryStream();
            boisSerializer.Serialize(obj, mem);
            return new MemoryStream(mem.ToArray()); 
        }
        catch (OutOfMemoryException)
        {
            var mem = new MemoryTributary();
            boisSerializer.Serialize(obj, mem);
            return new MemoryTributary(mem.ToArray());
        }
    }

    public static Stream ConvertObjectToStream(object obj)
    {
        if (obj == null) return null;
        var boisSerializer = new BoisSerializer();
        try
        {
            var mem = new MemoryStream();
            boisSerializer.Serialize(obj, obj.GetType(), mem);
            return new MemoryStream(mem.ToArray());
        }
        catch (OutOfMemoryException)
        {
            var mem = new MemoryTributary();
            boisSerializer.Serialize(obj, mem);
            return new MemoryTributary(mem.ToArray());
        }
    }

    public static T ConvertStreamToObject<T>(Stream stream)
    {
        stream.Position = 0;
        var boisSerializer = new BoisSerializer();
        var o = boisSerializer.Deserialize<T>(stream);
        return o;
    }

    public static object ConvertStreamToObject(Stream stream, Type type)
    {
        stream.Position = 0;
        var boisSerializer = new BoisSerializer();
        object o = boisSerializer.Deserialize(stream, type);
        return o;
    }

    public static Stream CompressStream(this Stream stream, LZ4Level lz4Level = LZ4Level.L00_FAST)
    {
        stream.Position = 0;
        var ms = new MemoryStream();
        var settings = new LZ4EncoderSettings { CompressionLevel = lz4Level };
        LZ4EncoderStream target = LZ4Stream.Encode(ms, settings);
        stream.CopyTo(target);
        target.Dispose();
        ms.Dispose();
        return new MemoryStream(ms.ToArray());
    }

    public static Stream DecompressStream(this Stream stream)
    {
        var ms = new MemoryStream();
        stream.Position = 0;
        LZ4DecoderStream source = LZ4Stream.Decode(stream);
        source.CopyTo(ms);
        source.Dispose();
        ms.Dispose();
        return new MemoryStream(ms.ToArray());

    }

public async Task UploadValueToContainer<T>(string containerName, string blobName, T obj)
    {
        Stream stream = Core.Tools.Helpers.ConvertObjectToStream(obj).CompressStream();
        CloudBlobContainer container = _blobClient.GetContainerReference(containerName);
        if (!container.Exists()) throw new Exception($"{containerName} Container has not been found.");
        CloudBlockBlob blobData = container.GetBlockBlobReference(blobName);
        await blobData.UploadFromStreamAsync(stream);
    }

    public async Task<T> DownloadValueFromContainer<T>(string containerName, string blobName) where T : new()
    {
        CloudBlobContainer container = _blobClient.GetContainerReference(containerName);
        if (!container.Exists()) throw new Exception($"{containerName} Container has not been found.");
        CloudBlockBlob blobData = container.GetBlockBlobReference(blobName);
        if (!blobData.Exists())
        {
            return new T();
        }

        try
        {
            var ms = new MemoryStream();
            await blobData.DownloadToStreamAsync(ms);
            return Core.Tools.Helpers.ConvertStreamToObject<T>(ms.DecompressStream());
        }
        catch (OutOfMemoryException)
        {
            var ms = new MemoryTributary();
            await blobData.DownloadToStreamAsync(ms);
            return Core.Tools.Helpers.ConvertStreamToObject<T>(ms.DecompressStream());
        }
    }
...