locked
Memory Leak to OpenFile Async in create_task?

    Question

  • In C++ code I opened file by using create_task. But there is no close file. Is OpenFileAsync in create_task will close old file and open a new file in the operation? Otherwise a memory leak may be happened.  In Win32 we deal with this kind of reentry by close previous file handle first.

    Charlie Chang L

    Friday, August 31, 2012 5:19 PM

Answers

  • add "delete stream" after the line ME->SetSource(...);

    see this sample: http://code.msdn.microsoft.com/windowsapps/File-access-sample-d723e597/sourcecode?fileId=44739&pathId=1519713705

          create_task(file->OpenAsync(FileAccessMode::Read)).then([this, file](task<IRandomAccessStream^> task) 
            { 
                try 
                { 
                    IRandomAccessStream^ readStream = task.get(); 
                    UINT64 const size = readStream->Size; 
                    if (size <= MAXUINT32) 
                    { 
                        DataReader^ dataReader = ref new DataReader(readStream); 
                        create_task(dataReader->LoadAsync(static_cast<UINT32>(size))).then([this, file, dataReader](unsigned int numBytesLoaded) 
                        { 
                            String^ fileContent = dataReader->ReadString(numBytesLoaded); 
                            delete dataReader; // As a best practice, explicitly close the dataReader resource as soon as it is no longer needed. 
                            OutputTextBlock->Text = "The following text was read from '" + file->Name + "' using a stream:\n\n" + fileContent; 
                        }); 
                    } 
                    else 
                    { 
                        delete readStream; // As a best practice, explicitly close the readStream resource as soon as it is no longer needed. 
                        OutputTextBlock->Text = "File " + file->Name + " is too big for LoadAsync to load in a single chunk. Files larger than 4GB need to be broken into multiple chunks to be loaded by LoadAsync."
                    } 
                } 
                catch(COMException^ ex) 
                { 
                    rootPage->HandleFileNotFoundException(ex); 
                } 
            }); 

    • Proposed as answer by Jesse Jiang Wednesday, September 05, 2012 7:18 AM
    • Marked as answer by Jesse Jiang Monday, September 10, 2012 6:36 AM
    Tuesday, September 04, 2012 4:02 AM

All replies

  • Hi Charlie,

    Your file will be closed when the stream accessing it is Closed. In C++, delete the stream (or DataReader or DataWriter) object.

    --Rob

    Friday, August 31, 2012 9:53 PM
    Owner
  • Hi Charlie,

    Your file will be closed when the stream accessing it is Closed. In C++, delete the stream (or DataReader or DataWriter) object.

    --Rob

    So when I opened a file and then a stream, the file was closed, that is fine but the stream still live. The problem still in there. I do not know where to delete the stream. For example,

    create_task(...).then([=](StorageFile^ file){  

    create_task(file->OpenAsync(...)).then(=)(IRandomAccessStream^ stream)   {        

    if (stream != nullptr) {           

    ME->SetSource(stream, file->ContentType);        

    }   

    }

    }

    You see, when I reentry this code clip, there is no place to delete stream!

    Is stream like ref new type that can be auto removed?

     

    Charlie Chang L

    Friday, August 31, 2012 10:32 PM
  • add "delete stream" after the line ME->SetSource(...);

    see this sample: http://code.msdn.microsoft.com/windowsapps/File-access-sample-d723e597/sourcecode?fileId=44739&pathId=1519713705

          create_task(file->OpenAsync(FileAccessMode::Read)).then([this, file](task<IRandomAccessStream^> task) 
            { 
                try 
                { 
                    IRandomAccessStream^ readStream = task.get(); 
                    UINT64 const size = readStream->Size; 
                    if (size <= MAXUINT32) 
                    { 
                        DataReader^ dataReader = ref new DataReader(readStream); 
                        create_task(dataReader->LoadAsync(static_cast<UINT32>(size))).then([this, file, dataReader](unsigned int numBytesLoaded) 
                        { 
                            String^ fileContent = dataReader->ReadString(numBytesLoaded); 
                            delete dataReader; // As a best practice, explicitly close the dataReader resource as soon as it is no longer needed. 
                            OutputTextBlock->Text = "The following text was read from '" + file->Name + "' using a stream:\n\n" + fileContent; 
                        }); 
                    } 
                    else 
                    { 
                        delete readStream; // As a best practice, explicitly close the readStream resource as soon as it is no longer needed. 
                        OutputTextBlock->Text = "File " + file->Name + " is too big for LoadAsync to load in a single chunk. Files larger than 4GB need to be broken into multiple chunks to be loaded by LoadAsync."
                    } 
                } 
                catch(COMException^ ex) 
                { 
                    rootPage->HandleFileNotFoundException(ex); 
                } 
            }); 

    • Proposed as answer by Jesse Jiang Wednesday, September 05, 2012 7:18 AM
    • Marked as answer by Jesse Jiang Monday, September 10, 2012 6:36 AM
    Tuesday, September 04, 2012 4:02 AM