2012-07-05 48 views
5

我最近一直在研究一個C#中的aspx動態圖像生成器,它最基本的是從「t」取一個查詢字符串值並將該字符串寫入圖像,然後返回一個JPG。C#圖像生成器 - 性能低下

它在本地完美運行,並在測試服務器上 - 圖像立即返回。

但是當在負載平衡的在線服務器上時,它有時可以正常工作。 但是,經常超時/花費一分鐘才能返回圖像。

我想我會問在這裏,如果在我的代碼中有任何明顯的問題會引起問題,那麼我會轉向服務器運營商,詢問爲什麼這種方式運行不正常。

下面是發電機的非常精簡的版本(其中也有完全相同的超時問題)

protected void Page_Load(object sender, EventArgs e) 
{ 

    // Set global stage dimensions 
    const int stageWidth = 500; 
    const int stageHeight = 200; 

    // Create Bitmap placeholder for new image  
    Bitmap createdImage = new Bitmap(stageWidth, stageHeight); 

    // Draw new blank image 
    Graphics imageCanvas = Graphics.FromImage(createdImage); 

    // Add text 
    if (!string.IsNullOrEmpty(Request.QueryString["t"])) 
    { 
     string imageText = Uri.UnescapeDataString(Request.QueryString["t"]).Trim(); 
     Font font = new Font("Arial", 22); 
     imageCanvas.DrawString(imageText, font, Brushes.White, 0, 0);    
    } 

    // Save 
    MemoryStream memStream = new MemoryStream(); 
    createdImage.Save(memStream, ImageFormat.Jpeg); 
    imageCanvas.Dispose(); 
    createdImage.Dispose(); 

    // Set filename/image format 
    Response.AppendHeader("content-disposition", "filename=MyImage"); 
    Response.ContentType = "image/jpeg";   

    // Send output to client 
    memStream.WriteTo(Response.OutputStream); 
    memStream.Dispose(); 
    Response.Flush(); 
} 
+0

是否超時在服務器上*由於負載過重*?服務器負載是否輕?你有沒有在你的本地服務器上強調這個測試? –

+8

另外,在'using'塊中包裝實現'IDisposable'的任何東西。如果在調用'.Dispose()'之前因任何原因拋出異常,您將泄漏資源......尤其是在負載下這會很糟糕。 –

+2

它沒有解釋超時,但我會使用一個普通的HttpHandler來代替使用Page實例,除非你做了一些不尋常的事情,否則你可能不需要UnescapeDataString調用。 – bmm6o

回答

3

有一些東西,我會改變:

  • 用來包圍與流使用關鍵字using
  • 改爲使用ashx處理程序。好像你正在使用一個aspx文件。對於這種場景,最好使用http處理程序,因爲它具有較小的生命週期。我用了很多次來提供圖像的縮略圖。
  • 使用一些緩存。也許你可以利用asp.net緩存功能,你可以找出是否有重複值的t,所以你將結果圖像存儲在緩存中,並避免每次寫入和創建一些蒸汽
  • 最後但並非最不重要,請嘗試檢查服務器是否具有最新的sp和更新。有一些情況下,如果有某些更新錯誤,應用程序將表現得很奇怪,

此外,它可能與網站本身相關聯。您可以查看服務器的性能計數器,以查看是否報告了一些異常情況。

希望它有幫助。

1

你可以節省一些內存,並可能通過直接保存到輸出流,而不是使用一個內存流來獲得性能:

createdImage.Save(Response.OutputStream, ImageFormat.Jpeg); 

另一個問題可能是你的代碼是在.aspx頁面。它可能會經常重新編譯。我會建議一個http處理程序:

public class MyHttpHandler : IHttpHandler 
{ 
    public void ProcessRequest(HttpContext context) 
    { 
     // prepare image like you did 
     memStream.WriteTo(context.Response.OutputStream); 
    } 

    // Override the IsReusable property. 
    public bool IsReusable 
    { 
     get { return true; } 
    } 
}