コードには、誤動作の原因となる完全に独立した問題が少なくとも 2 つあります。
問題 #1: GDI+ エラー
これは、エコシステムのいたるところで発生し続ける、繰り返し発生する問題です。私はそれを持っていました、私はそれを修正することができましたが、今では正確にどのように思い出せません. 問題を再現しようとしましたが、エラーを受け取ることができませんでした。
このスレッドを確認することをお勧めします
: http://forums.asp.net/t/624305.aspx/1
- 他の描画を続行する前に、すべての Bitmap インスタンスを破棄したことを確認する
- (興味深いもの): GC.Collect()の実行 (おそらく各ビットマップのレンダリング後)
これは、私があなたに答えを出そうとした主な理由ではありません. あなたは、私がこのような状況に陥らないようにするために私が普段行っているすべてのこと (セキュリティ、信頼など) を既に行っているようです (あなたは行ったと言っています)。さらに、必要以上に自分の後片付けをします(私の回答を読んでいるときにわかるように、少し多すぎます)。
あなたのコードには、おそらく気付いていない 2 つ目の問題があることがわかりました。私自身の VS 環境でその問題を解決するだけで、(IIS 7 と Express と ASP 開発サーバーの両方で) ビットマップのレンダリングに成功しました。
アプリケーションのコードを少し再編成することで、問題 1 を解決できる可能性が高くなります。だから:問題#2について私が言わなければならないことをチェックしてください.
問題 #2: ストリームを同時に破棄して返すことはできません
次のように、作成して破棄したばかりのストリームを行って返すことはできません。
public static Stream SomeMethod() {
using (MemoryStream stream = new MemoryStream()) {
// write something to the stream
return stream;
}
}
そのコードが ASP.NET 開発サーバーで実際にどのように機能するのか、私にはよくわかりません。ここで指摘しようとしている問題は、コードが常に ObjectDisposedException をスローすることです (コードをサービスとして実行しているか、インタラクティブなユーザー空間で実行しているかに関係なく)。
誰がストリームを閉じますか? 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();
}
}
アプリケーションのニーズについて自分で推測できるようにすることで、この他のソリューションの方がさらに優れていると思います。
これらの生成されたチャート イメージを< img >タグに戻して Web ブラウザーに戻したい場合、たとえば ASP.NET ジェネリック ハンドラーを使用してこれを実現している場合は、次の OutputStream を渡すことができます。次のように、結果の byte[] (または Stream) を取得する代わりに、現在の WebResponse を描画メソッドに渡します。
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
}
}