Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A fix for huge memory usage for larger files. #393

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
62 changes: 45 additions & 17 deletions src/source/RazorEngine.Core/Templating/TemplateBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,28 +207,31 @@ private static void StreamToTextWriter(MemoryStream memory, TextWriter writer)
/// Runs the template and returns the result.
/// </summary>
/// <param name="context">The current execution context.</param>
/// <param name="reader"></param>
/// <param name="outputWriter"></param>
/// <returns>The merged result of the template.</returns>
#if RAZOR4
public async Task Run(ExecuteContext context, TextWriter reader)
public async Task Run(ExecuteContext context, TextWriter outputWriter)
#else
void ITemplate.Run(ExecuteContext context, TextWriter reader)
void ITemplate.Run(ExecuteContext context, TextWriter outputWriter)
#endif
{
_context = context;

StringBuilder builder = new StringBuilder();
using (var writer = new StringWriter(builder))
string tempFilePath = Path.GetTempFileName();

try
{
_context.CurrentWriter = writer;
using (var writer = new StreamWriter(tempFilePath))
{
_context.CurrentWriter = writer;
#if RAZOR4
await Execute();
#else
Execute();
Execute();
#endif
writer.Flush();
_context.CurrentWriter = null;

writer.Flush();
_context.CurrentWriter = null;
}

if (Layout != null)
{
Expand All @@ -237,23 +240,48 @@ void ITemplate.Run(ExecuteContext context, TextWriter reader)

if (layout == null)
{
throw new ArgumentException("Template you are trying to run uses layout, but no layout found in cache or by resolver.");
throw new ArgumentException(
"Template you are trying to run uses layout, but no layout found in cache or by resolver.");
}

// Push the current body instance onto the stack for later execution.
var body = new TemplateWriter(tw => tw.Write(builder.ToString()));
context.PushBody(body);
var body = new TemplateWriter(
tw =>
{
using (var reader = new StreamReader(tempFilePath))
{
// Push the current body instance onto the stack for later execution.
while ( !reader.EndOfStream)
{
tw.Write(reader.ReadLine());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReadLine does not include the new line characters. That's why some tests are failing.

}
}
});

context.PushBody(body);

context.PushSections();

#if RAZOR4
await layout.Run(context, reader);
await layout.Run(context, outputWriter);
#else
layout.Run(context, reader);
layout.Run(context, outputWriter);
#endif
return;
}

reader.Write(builder.ToString());
using (var reader = new StreamReader(tempFilePath))
{
// Push the current body instance onto the stack for later execution.
while (!reader.EndOfStream)
{
outputWriter.Write(reader.ReadLine());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReadLine does not include the new line characters. That's why some tests are failing.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many thanks :)

I had a problem generating huge files, that's why I tried to use a file
stream instead of memory one.

Does that change look sensible?

Possibly the best approach would be to generate small parts of the text at
once and append them to file.

Cheers,
AD

On Sat, Jul 16, 2016 at 5:20 PM, campersau [email protected] wrote:

In src/source/RazorEngine.Core/Templating/TemplateBase.cs
#393 (comment):

#endif
return;
}

  •            reader.Write(builder.ToString());
    
  •            using (var reader = new StreamReader(tempFilePath))
    
  •            {
    
  •                // Push the current body instance onto the stack for later execution.
    
  •                while (!reader.EndOfStream)
    
  •                {
    
  •                    outputWriter.Write(reader.ReadLine());
    

ReadLine does not include the new line characters. That's why some tests
are failing.


You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/Antaris/RazorEngine/pull/393/files/605e08f364f35515d3f4da32ab4a0164a493ce5b#r71067372,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAyu5uoPDIymOAH48P8qLWl_oZ3sW7tRks5qWPamgaJpZM4I5pRR
.

}
}

}
finally
{
File.Delete(tempFilePath);
}
}

Expand Down