我有一个 asp.net 处理程序,它被调用来生成动态图像(圆形图标指示填充级别和不同填充级别的不同颜色)。图像完全在内存中生成,过程中不加载图像文件。这段代码在生产中 99.9% 的时间都可以工作,但是偶尔处理程序会退出工作,并抛出下面的异常。IIS 重置将解决此问题。我正在运行 Windows Server 2008 r2 标准版,其中包含所有最新和最好的更新。我在下面包含了相关代码。任何想法表示赞赏。
我已经看过几十篇文章和 microsoft kb 文章,几乎所有文章都围绕文件和目录权限展开。这似乎不适用于这里。
异常:System.Runtime.InteropServices.ExternalException:GDI+ 中出现一般错误。在 System.Drawing.Image.Save(Stream 流,ImageCodecInfo 编码器,EncoderParameters encoderParams) 在 System.Drawing.Image.Save(Stream 流,ImageFormat 格式)
代码:
var fillPercentString = context.Request.QueryString["fillPercent"];
var iconSizeString = context.Request.QueryString["size"];
var colorString = context.Request.QueryString["fillColor"];
double fillPercent;
double.TryParse(fillPercentString, out fillPercent); //0.01 * (!string.IsNullOrEmpty(fillPercentString) ? int.Parse(fillPercentString) : 0);
fillPercent = 0.01 * fillPercent;
var iconSize = !string.IsNullOrEmpty(iconSizeString) ? int.Parse(iconSizeString) : 16;
var iconWidth = iconSize;
var iconHeight = iconSize;
var memStream = new MemoryStream();
var color = System.Drawing.Color.FromName(colorString);
if (iconSize < 0)
{
throw new InvalidOperationException("Invalid size.");
}
if (fillPercent < 0 || fillPercent > 100)
{
throw new InvalidOperationException("Invalid fill percentage.");
}
using (var bitmap = new Bitmap(iconWidth + 1, iconHeight + 1))
using (var graphic = Graphics.FromImage(bitmap))
using (var backgroundFillBrush = new SolidBrush(Color.White))
using (var fillBrush = new SolidBrush(color))
using (var outlinePen = new Pen(Color.Black, 1f))
{
graphic.SmoothingMode = SmoothingMode.AntiAlias;
var circleBounds = new Rectangle(0, 0, iconWidth, iconHeight);
// fill with transparent
graphic.FillRectangle(backgroundFillBrush, 0, 0, bitmap.Width, bitmap.Height);
// fill a full circle
graphic.FillEllipse(fillBrush, circleBounds);
// draw a rectangle to clip out unneeded region
if (fillPercent < 1.00)
{
graphic.FillRectangle(backgroundFillBrush, new RectangleF(0, 0, bitmap.Width, (int)((1 - fillPercent) * bitmap.Height)));
}
// draw the circle outline
graphic.DrawEllipse(outlinePen, circleBounds);
// finalize and save to cache
bitmap.MakeTransparent(bitmap.GetPixel(1, 1));
bitmap.Save(memStream, ImageFormat.Png);
var returnBytes = memStream.ToArray();
// write the image to the output stream
if (context.Response.IsClientConnected)
{
context.Response.ContentType = "image/png";
context.Response.OutputStream.Write(returnBytes, 0, returnBytes.Length);
}
}