0

I create a app to read ZipArchive(100+ photo),And Use Stream, MemoryStream, IRandomAccessStream, and BinaryReader to setSource of the bitmapImage.

private byte[] GetBytes(ZipArchiveEntry entity)
    {
        Stream stream = entity.Open();
        MemoryStream ms = new MemoryStream();
        BinaryReader reader = null;
        byte[] imageData = null;
        try
        {
            stream.CopyTo(ms);
            imageData = new byte[ms.Length];
            string fileclass = "";
            reader = new BinaryReader(ms);
            ms.Seek(0, 0);
            imageData = reader.ReadBytes((int)ms.Length);
            //Verify png jpg bmp
            some code and return imageData
            //throw exception,return null
            else
            {
                throw new Exception();
            }
        }
        catch (Exception ex)
        {
            return null;
        }
        //Dispose
    }

BitmapImage.SetSource by byte[]

public async Task<MangaPageEntity> GetImageFromZipArchiveEntry(ZipArchiveEntry entity, int index)
    {
        MangaPageEntity mpe = new MangaPageEntity();
        mpe.Index = index;
        IRandomAccessStream iras = null;
        try
        {
            byte[] data = GetBytes(entity);
            iras = data.AsBuffer().AsStream().AsRandomAccessStream();
            iras.Seek(0);
            await mpe.Picture.SetSourceAsync(iras);
        }//catch and dispose
        return mpe;

In this way, It use too many memory too run at phone ..

Romasz
  • 29,662
  • 13
  • 79
  • 154

1 Answers1

1

Try to put your streams and other IDisposable into using statement:

private byte[] GetBytes(ZipArchiveEntry entity)
{
    using (Stream stream = entity.Open())
    using (MemoryStream ms = new MemoryStream())
    {
        byte[] imageData = null;
        try
        {
            stream.CopyTo(ms);
            imageData = new byte[ms.Length];
            string fileclass = "";
            using (BinaryReader reader = new BinaryReader(ms))
            {
                ms.Seek(0, 0);
                imageData = reader.ReadBytes((int)ms.Length);
            }              
            //Verify png jpg bmp some code and return imageData
            //throw exception,return null
            else
            {
                throw new Exception();
            }
        }
        catch (Exception ex)
        {
            return null;
        }
    }
    //Dispose
}

public async Task<MangaPageEntity> GetImageFromZipArchiveEntry(ZipArchiveEntry entity, int index)
{
    MangaPageEntity mpe = new MangaPageEntity();
    mpe.Index = index;
    try
    {
        byte[] data = GetBytes(entity);
        using (IRandomAccessStream iras = data.AsBuffer().AsStream().AsRandomAccessStream())
        {
            iras.Seek(0);
            await mpe.Picture.SetSourceAsync(iras);
        }
    }//catch and dispose
    return mpe;
}

When your code leaves using it calls Dispose(). Some more to read: Uses of “using” in C#, What is the C# Using block and why should I use it? and probably some more.

Romasz
  • 29,662
  • 13
  • 79
  • 154
  • OK,I will try it. But I don't know the different between "using" and try{} catch{} finally – MarvelTitle Sep 16 '17 at 16:13
  • @MarvelTitle Then you need to do [some lecture](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/try-catch). Generally try/catch/finally has nothing to do with memory and *IDisposable*. – Romasz Sep 16 '17 at 16:16
  • I think the main problem is the ZipArchive file is too large. Thanks. – MarvelTitle Sep 16 '17 at 16:25
  • Maybe I could make it load slowly, but I really don't know how to do it at uwp – MarvelTitle Sep 16 '17 at 16:28
  • @MarvelTitle Generaly there may be many other thigns that give memory problems, however leaving undisposed streams is for sure one of them. – Romasz Sep 16 '17 at 22:19
  • the memory usage is same as try{} catch{} finally. – MarvelTitle Sep 17 '17 at 01:32
  • @MarvelTitle Have you tried to use memory profiler to see when and what is happening? I'm also not sure what you are trying to achieve, but taking a closer look at your code shows, that you are allocating the same memory couple of times - in memory stream, in byte array - think if that is necessary. – Romasz Sep 17 '17 at 05:35
  • sometimes ZipArchiveEntry.Open() return a can't seek stream, so I copy to a memory stream that can seek.. When I call the GetBytes method , memory dramatic increase.. – MarvelTitle Sep 18 '17 at 04:51
  • @MarvelTitle Note sure if you need here byte array along with memorey stream. Probably you can read for original stream via a buffer, or maybe omit the byte array. It's for sure dramatic increase if you allocate so much memory. – Romasz Sep 18 '17 at 09:32