5

我最近一直在用 C# 开发一个 aspx 动态图像生成器,它最基本的功能是从“t”中获取一个查询字符串值并将该字符串写入图像,然后返回一个 JPG。

它在本地和测试服务器上完美运行 - 图像立即返回。

但是当在负载平衡的实时服务器上时,有时它可以正常工作。但是通常它会超时/最多需要一分钟才能返回图像。

我想我会在这里询问我的代码中是否有任何明显的东西会导致问题,然后我转向服务器操作员询问为什么这不能正常工作。

下面是一个非常精简的生成器版本(也有完全相同的超时问题)

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();
}
4

2 回答 2

3

有一些事情我会改变:

  • 使用关键字包围流using
  • 请改用 ashx 处理程序。好像您正在使用 aspx 文件。对于这种情况,最好使用 http 处理程序,因为它的生命周期更短。我已经多次使用它来提供图像的缩略图。
  • 使用一些缓存。或许你可以利用asp.net的缓存特性,你可以找出t是否有重复值,这样你就可以将生成的图像存储在缓存中,避免每次都写入和创建一些steam
  • 最后但同样重要的是,尝试检查服务器是否有最新的 sp 和更新。在某些情况下,如果缺少某些更新,应用程序会表现得很奇怪,

它也可以与网络场本身相关联。您可以查看服务器的性能计数器以查看是否报告了一些异常情况。

希望能帮助到你。

于 2012-08-06T19:17:36.373 回答
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; }
   }
}
于 2012-08-06T19:59:59.083 回答