C# Graphics DrawString画笔慎用Brushes,会报参数无效
今天用C#调用DrawString往一张图片写入文字的时候,出现了“参数无效”的错误。framework版本是2.0的,系统win2003。
主要问题描述:一个生成图片的ashx页面,执行到DrawString时就报错,重启iis后第一次或者第二次的访问能正常生成图片,后续的访问执行到DrawString时就报错了。
[ArgumentException: 参数无效。]
System.Drawing.Graphics.CheckErrorStatus(Int32 status) +1048569
System.Drawing.Graphics.DrawString(String s, Font font, Brush brush, RectangleF layoutRectangle, StringFormat format) +211
System.Drawing.Graphics.DrawString(String s, Font font, Brush brush, Single x, Single y) +53
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +406
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +76
简单示例代码如下
public void ProcessRequest(HttpContext context) { Bitmap nbitmap = new Bitmap(1000, 1000); Graphics g = Graphics.FromImage(nbitmap); Font font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Italic); Brush brush = Brushes.Black; g.DrawString("测试字符串", font, brush, 10, 10);/////运行到这句报参数无效 g.Dispose(); font.Dispose(); brush.Dispose(); nbitmap.Save(context.Server.MapPath("~/upload/cert" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".jpg")); nbitmap.Dispose(); }
后面测试及参考别人的代码后发现画笔对象使用的是Brush子类SolidBrush,而不是使用Brushes.Black,于是修改成下面的代码
public void ProcessRequest(HttpContext context) { Bitmap nbitmap = new Bitmap(1000, 1000); Graphics g = Graphics.FromImage(nbitmap); Font font = new Font(FontFamily.GenericSansSerif, 10, FontStyle.Italic); //Brush brush = Brushes.Black; SolidBrush brush = new SolidBrush(Color.Black);//替换成Brush子类SolidBrush就没问题了,不再报参数无效错误 g.DrawString("测试字符串", font, brush, 10, 10);/////运行到这句报参数无效 g.Dispose(); font.Dispose(); brush.Dispose(); nbitmap.Save(context.Server.MapPath("~/upload/cert" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".jpg")); nbitmap.Dispose(); }
为毛不能直接使用Brushes预定义的画笔,蛋痛,ms的bug。。?或者为毛iis重启后第一次或者第二次访问能正常运行,后续的访问到到DrawString这句就报参数无效错误了。。
最后更新:brush.Dispose();最后释放画笔的问题。
Brushes.Black是静态对象,Dispose释放对应的HBrush句柄,以后再调用就出错了。
从报错信息看也很明显,这是DrawString方法的最后两行:
int status = SafeNativeMethods.Gdip.GdipDrawString(new HandleRef(this, this.NativeGraphics), s, s.Length
, new HandleRef(font, font.NativeFont), ref layoutRect, new HandleRef(format, handle), new HandleRef(brush, brush.NativeBrush));
this.CheckErrorStatus(status);
前一句调用native gdi函数去执行,后一句检查win32返回状态码。
在CheckErrorStatus方法中,如果status != 0,则:
throw SafeNativeMethods.Gdip.StatusException(status);
把error status转成相应的各类Excetion
其中:
case 2:
return new ArgumentException(SR.GetString("GdiplusInvalidParameter"));
你看到的就是ArgumentException,对应win32 error code是2
表示传到GdipDrawString函数中的某个参数是无效的。
加支付宝好友偷能量挖...
原创文章,转载请注明出处:C# Graphics DrawString画笔慎用Brushes,会报参数无效