您的代码中至少有 2 个完全独立的问题导致其出现故障。
问题#1:GDI+ 错误
这是一个反复出现的问题,在生态系统中不断出现。
我有它,我设法修复它,但现在我不记得具体是如何修复的。
我尝试复制你的问题,但没有收到失败信息。
我建议你检查这个线程:http://forums.asp.net/t/624305.aspx/1 http://forums.asp.net/t/624305.aspx/1一些人很高兴地通过以下方式克服了这个问题:
- 确保他们在继续其他绘图之前处理掉所有位图实例
- (有趣的一个): 做一个GC.Collect()(可能在每次位图渲染之后)
这并不是我想尝试帮助您找到答案的主要原因。
看来你已经做了(你说你做了)我通常做的所有事情,以确保我不会陷入这种情况(安全、信任等)。此外,您自己清理的次数超出了需要的范围(在阅读我的答案时您会发现有点太多了)。
我发现您的代码有第二个问题您可能没有意识到。
通过在我自己的 VS 环境中简单地解决这个问题,我成功地渲染了位图(在 IIS 7 和 Express 以及 ASP 开发服务器中)。
通过在应用程序代码中进行一些组织,您很有可能能够解决问题#1。所以:请看看我对问题 2 的看法。
问题#2:流不能同时释放和返回
您无法返回刚刚创建的流并处置 like:
public static Stream SomeMethod() {
using (MemoryStream stream = new MemoryStream()) {
// write something to the stream
return stream;
}
}
我真的不明白这段代码在 ASP.NET Development Server 中实际上是如何工作的。
我在这里试图指出的问题是,您的代码总是会抛出 ObjectDisposeException(无论您是将代码作为服务运行还是在交互式用户空间中运行):
谁关闭了流?终止using陈述。
问题 #2 的可能解决方案
解决这个特定问题(可能会使用比您预期更多的内存)的快速解决方案是让您的方法返回 byte[] 而不是流。
public static byte[] SomeMethod() {
using (MemoryStream stream = new MemoryStream()) {
// ... create bitmap and render things ...
// write something to the stream
bitmap.Save(stream, ImageFormat.Png);
return stream.ToArray();
}
}
让我自己对您的应用程序需求做出假设,我想说这个其他解决方案可能会更好:
If您希望将这些生成的图表图像返回到标记回 Web 浏览器,并且您通过 ASP.NET 通用处理程序来完成此操作,然后您可以传递当前 WebResponse 的 OutputStreamto您的绘图方法,而不是采用结果 byte[] (或 Stream)from它,就像这样:
In HTML:
<img src="path/Foo.ashx" alt="chart" ... etc ... />
在应用程序中时:
public class Foo : IHttpHandler {
public void ProcessRequest(HttpContext context) {
context.Response.ContentType = "application/octet-stream";
Stream alreadyExistingStream = context.Response.OutputStream;
Etc.SomeMethod(stream);
}
}
public class Etc {
public static void SomeMethod(Stream stream) {
// There used to be a using here that would create a stream
// simply because the parameter name **stream** is the same as the former local var's name
// the instructions that do the drawing of things
// + saving of the resulting Bitmap **to** the stream
// keep on compiling without any problems
// draw things to a bitmap
// write the bitmap to the stream
bitmap.Save(stream, ImageFormat.Png);
// returning stuff is not needed anymore
// This used to be the time and place where the stream would be disposed
// and it's resources given back to the community
}
}