2013-07-11 2 views
4

У меня есть страница ASPX, которая отображает все, что есть в ее строке, как вертикальный текст и возвращает PNG. Он отлично работает.Intermittent System.Drawing/GDI + «Общая» ошибка

У меня есть только один клиент, который столкнулся с проблемой. Каждые несколько дней страница перестает работать и бросает страшную ошибку GDI + «общий».

Error: System.Runtime.InteropServices.ExternalException (0x80004005): A generic error occurred in GDI+. 
at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams) 
at System.Drawing.Image.Save(Stream stream, ImageFormat format) 
... 

Я не знаю, почему возникает ошибка или почему она в конечном итоге уходит. Я смог загрузить тестовый ASPX-файл в свою установку, в которой использовался аналогичный код с несколькими вариантами, чтобы увидеть, могу ли я определить проблему. Я обнаружил, что если я изменил ImageFormat из Png в Jpeg, ошибка исчезла.

Я мог бы сменить продукт для рендеринга JPEG вместо PNG. Однако я не могу понять, будет ли это в конечном итоге приводить к ошибкам с перерывами, как сейчас.

Кто-нибудь знает, что может вызвать такую ​​проблему? Благодаря! Код ниже.

Обновление: Сервер клиентов - это поле Windows Server 2008 R2 с IIS 7.5, а мое приложение работает на .NET 4.0.

protected void Page_Load(object sender, EventArgs e) 
    { 
     byte[] image = GetImageBytes(this.Text); 
     if (image != null) 
     { 
      Response.ClearContent(); 
      Response.ClearHeaders(); 
      Response.ContentType = "image/png"; 
      Response.OutputStream.Write(image, 0, image.Length); 
     } 
    } 

    private byte[] GetImageBytes(string text) 
    { 
     var font = new Font("Tahoma", 11, FontStyle.Bold, GraphicsUnit.Pixel); 

     // Create an image the size of the text we are writing 
     Bitmap img = new Bitmap(1,1); 
     var graphics = Graphics.FromImage(img); 
     int width = (int)graphics.MeasureString(text, font).Width; 
     int height = (int)graphics.MeasureString(text, font).Height; 
     img = new Bitmap(img, new Size(width, height)); 

     // Draw the text onto the image 
     graphics = Graphics.FromImage(img); 
     graphics.Clear(Color.Transparent); 
     graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
     graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; 
     graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
     graphics.DrawString(text, font, new SolidBrush(Color.Black), 0, 0); 
     graphics.Flush(); 

     // Rotate the image to be vertical 
     img.RotateFlip(RotateFlipType.Rotate270FlipNone); 

     var stream = new System.IO.MemoryStream(); 
     img.Save(stream, ImageFormat.Png); 
     stream.Position = 0; 
     return stream.ToArray(); 
    } 
+1

Это может быть драйвер видеокарты с ошибкой. Проверьте также, если у вас закончилась куча рабочего стола. Если он заполнен, запись журнала событий записывается в журнал системных событий. Проверьте журнал приложений и системных событий на наличие подозрительных событий. –

+1

Вероятно, вам следует удалять шрифт, img, графику и объекты потока. – LarsTech

+0

@LarsTech, правда, поэтому в моем ответе я предложил новые коды :) – Fredou

ответ

3

I would say that the flush could be the issue

исполнение Forces всех отложенных графических операций и немедленно возвращается, не дожидаясь операции до конца.

Этот участник перегружен. Для получения полной информации об этом члене, включая синтаксис, использование и примеры, щелкните имя в списке перегрузки.

Вы можете попробовать это, чтобы узнать, есть ли у вас проблема?

private byte[] GetImageBytes(string text) 
    { 
     using (var font = new Font("Tahoma", 20, FontStyle.Bold, GraphicsUnit.Pixel)) 
     using (var img = new Bitmap(1, 1)) 
     { 
      int width; 
      int height; 
      using (var graphics = Graphics.FromImage(img)) 
      { 
       width = (int)graphics.MeasureString(text, font).Width; 
       height = (int)graphics.MeasureString(text, font).Height; 
      } 
      using (var realImg = new Bitmap(img, new Size(width, height))) 
      { 
       using (var graphics = Graphics.FromImage(realImg)) 
       { 
        graphics.Clear(Color.Transparent); 
        graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 
        graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; 
        graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
        graphics.DrawString(text, font, new SolidBrush(Color.Black), 0, 0); 
       } 

       realImg.RotateFlip(RotateFlipType.Rotate270FlipNone); 

       using (var stream = new System.IO.MemoryStream()) 
       { 
        realImg.Save(stream, System.Drawing.Imaging.ImageFormat.Png); 
        stream.Position = 0; 
        return stream.ToArray(); 
       } 
      } 
     } 
    } 
+0

Fredou - я использовал консольное приложение для запуска кода миллионы раз в течение одного процесса, и я не сталкивался с какими-либо проблемами. Однако это действительно похоже на хорошее изменение кода, чтобы сделать так или иначе. Благодаря! –

+0

Извините, вы только что заметили, что вы также удалили вызов Flush вместе с операциями using. Я попробую. –

+0

@BarryFandango, Да, я удалил его, так как я не вижу необходимости этого флеш-вызова, и я также обновил свой код, так как я забыл использовать его на графике. – Fredou

Смежные вопросы