我有一个asp.net处理程序被调用来生成动态图像(圆形图标表示填充级别和不同填充级别的不同颜色)。图像完全在内存中生成,并且在此过程中不会加载任何图像文件。此代码在生产中有99.9%的时间可用,但有时处理程序退出工作,抛出下面的异常。 IIS重置将解决问题。我正在运行Windows Server 2008 r2标准,包含所有最新和最好的更新。我在下面列出了相关代码。任何想法都表示赞赏。
我已经查看过几十篇文章和微软的kb文章,几乎所有文章都围绕着文件和目录权限。这似乎不适用于此。
例外: System.Runtime.InteropServices.ExternalException:GDI +中发生一般错误。 在System.Drawing.Image.Save(Stream stream,ImageCodecInfo encoder,EncoderParameters encoderParams) 在System.Drawing.Image.Save(Stream stream,ImageFormat format)
代码:
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);
}
}