What is important to know about Response.WriteFile? Specifically, Is it fast? Benchmark the performance of Response.WriteFile, and see if the file system caching makes it as fast as caching separately. Write a binary file, such as a PNG, to the Response buffer.
I have examined various solutions for inserting another file into an ASPX page, including old-school SSI directives. In studying the IIS7 file system cache, I learned that IIS7 will cache files that are accessed more than once every 10 seconds.
Static caches. Additionally, I benchmarked and optimized ways to cache application settings. In that article, I found that using static properties is 30 times faster than using appSettings.
The Response.WriteFile() method directly inserts the bytes of another file into your ASPX page. Here is the "before" code in which I inserted a PNG image into the ASPX file (which is displayed as a graphic in the browser).
using System;
using System.Web;
using System.Web.UI;
using System.IO;
using System.Diagnostics;
public partial class C_Default : Page
{
protected override void OnLoad(EventArgs e)
{
//
// Always give visitors the image
//
WriteData();
base.OnLoad(e);
}
private void WriteData()
{
Response.ContentType = "image/png";
Response.WriteFile("Logo-Pale-Fireworks.png", true);
}
}No. Let's say that the above code runs 1,000 times a minute. In my testing, that approach is many times slower that using a custom C# byte[] cache.
Why is that? For some reason, the file system cache is easily defeated, at least on the ASP.NET development server. This problem would likely still be present on the deployment installation. (Note that I couldn't find any difference by using the readIntoMemory option.)
Why not just put the image's bytes into an array and store it in a static class? I felt the overhead of the C# code might outweigh the benefits here, but I was wrong. Using the byte[] cache here can ensure that the cache will be hit.
using System;
using System.Web;
using System.Web.UI;
using System.IO;
using System.Diagnostics;
public partial class C_Default : Page
{
protected override void OnLoad(EventArgs e)
{
//
// Always give visitors the image
//
WriteData();
base.OnLoad(e);
}
private void WriteData()
{
Response.ContentType = "image/png";
Response.BinaryWrite(SiteData.Logo);
}
}Static class. In the above code block, you will see the line Response.BinaryWrite(SiteData.Logo);. This is accessing the static property containing the bytes of the logo ("Logo-Pale-Fireworks.png"). Here's that code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
public static class SiteData
{
public static byte[] Logo
{
get
{
return _logoBytes;
}
}
static byte[] _logoBytes;
static SiteData()
{
//
// Caching the file this way is much faster than using WriteFile
//
_logoBytes = File.ReadAllBytes(HttpContext.Current.Server.MapPath(
"~/C/Logo-Pale-Fireworks.png"));
}
}App_Code folder. I put the above code in a new file in the App_Code file. It uses a static constructor, which means it will only run once (usually lazily). Look at how the code is more complicated.
Yes. And quite a lot faster as well. Even in ideal conditions on the server, the first approach (WriteFile) will be slower because the file may not be in the file system cache. The second approach guarantees the file will be in memory.
Benchmark details. There is a really obvious performance improvement by manually caching bytes. The above code blocks were executed 1000 times each, with the response buffer being cleared with Response.Clear() each iteration. Values are 10.680956, 0.094 seconds.
Don't rely on file system caches for optimal performance. Use Cache[] objects or static classes to ensure a static resource is resident in memory. My experience with ASP.NET is that creating custom C# code is often far better for performance than using ASP.NET methods such as Response.WriteFile.