2012-10-23 46 views
4

我嘗試將png保存到內存流時出錯。在我的ASP.NET開發服務器上一切正常,但是當我在IIS7下運行網站時 - 會產生一個錯誤。另外當我嘗試保存JPG格式 - 一切都是正確的。在IIS中,我已將.NET可信級別設置爲「完全」。但它仍然沒有工作。我需要你的幫助。當我在IIS7中將png保存到MemoryStream時發生了一般性錯誤

private static Stream DrawBarChart(IEnumerable<Tuple<string, ulong, double>> data){ 
using (MemoryStream stream = new MemoryStream()) 
{ 
    var canvasWidth = PageSize.A4.Width; 
    var canvasHeight = PageSize.A4.Height; 

    using (
     System.Drawing.Image bitmap = new Bitmap((int) canvasWidth, 
               (int) canvasHeight)) 
    { 
     using (var graphics = Graphics.FromImage(bitmap)) 
     { 
      var penBlack1 = new Pen(Brushes.Black, 1); 

      graphics.DrawLine(penBlack1, 0, 0, canvasWidth, 0); 
      graphics.DrawLine(penBlack1, 0, 0, 0, canvasHeight); 

      graphics.Save(); 
     } 
     bitmap.Save(stream, ImageFormat.Png); 

    stream.Flush(); 
    stream.Position = 0; 

    return stream; 
    } 
} 

}

+0

難道有事情做與GDI +(該顯卡僅僅是封裝)不支持服務? [源代碼](http://msdn.microsoft.com/en-us/library/ms533798%28VS.85%29.aspx):_「GDI +函​​數和類不支持在Windows服務中使用。嘗試使用Windows服務中的這些函數和類可能會產生意想不到的問題,例如服務性能下降和運行時異常或錯誤。「_ – CodeCaster

+0

可以使用什麼替代方法來生成圖片? – Alexander

+0

Graphics.Save不是你所想的那樣。去谷歌上查詢。 – usr

回答

3

有在你的代碼至少2個完全獨立的問題,導致其故障。

問題#1:GDI +錯誤

這是一個反覆出現的問題上如雨後春筍般遍佈在生態系統中的位置保持。 我有它,我設法修復它,現在我不記得如何。 我試圖複製你的問題,我沒有收到失敗。

我建議你查一下這個線程:http://forums.asp.net/t/624305.aspx/1 這裏有些人也樂意設法克服的問題:

  • 確保他們設置所有的位圖實例與其他圖紙
  • 執行之前( 有趣的):做一個GC.Collect的()(可能是每個位圖渲染後)

這不是我爲什麼試圖幫助你解答問題的主要原因。 看來你已經做了(你說你做過)所有我通常做的事情,以確保我不會在這種情況下(安全,信任等)結束。此外,你可以自己清理超過需要(有點太多了,因爲你會在閱讀我的答案時發現)。

我發現你的代碼有第二個問題,你可能不知道。 通過簡單地在我自己的VS環境中解決這個問題,我成功地呈現了Bitmaps(在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 Development Server中的工作原理。 我想在這裏指出的問題是,你的代碼總是拋出的ObjectDisposedException(不管你正在運行的代碼作爲一種服務或交互式用戶空間):

Cannot access a closed stream

誰關閉流?使用聲明終止

可能的解決方案,以問題#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通用處理程序完成此操作,那麼您可以將當前WebResponse的OutputStream傳遞給您的繪圖方法,而不是採用得到的字節[](或流)它,就像這樣:

在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 
} 

} 
相關問題