2012-07-05 12 views
5

Ho lavorato di recente a un generatore di immagini dinamiche aspx in C# che, nella sua forma più semplice, prende un valore di querystring da "t" e scrive quella stringa su un'immagine, quindi restituisce un JPG.C# Image Generator - Slow Performance

Ha funzionato perfettamente a livello locale e su un server di prova - le immagini sono state restituite all'istante.

Ma quando su server live con carico bilanciato, a volte funziona correttamente. Ma più che spesso scade/impiega fino a un minuto per restituire l'immagine.

Ho pensato di chiedere qui se c'è qualcosa di ovvio nel mio codice che potrebbe causare problemi, prima di rivolgersi agli operatori di server per chiedere perché questo non funziona bene.

Qui di seguito è una versione molto semplificata del generatore (che ha anche gli stessi problemi esatti timeout)

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

È il timeout sui server * a causa del carico pesante *? Il server carica la luce? Hai sottolineato questo test sul tuo server locale? –

+8

Inoltre, avvolgere tutto ciò che implementa 'IDisposable' in un blocco' using'. Se un'eccezione viene lanciata per qualsiasi motivo prima di chiamare '.Dispose()' si verificheranno perdite di risorse ... il che sarebbe particolarmente pericoloso sotto carico. –

+2

Non spiega i timeout, ma userei un semplice HttpHandler per questo usando invece un'istanza di Pagina e, a meno che tu stia facendo qualcosa di insolito, probabilmente non hai bisogno della chiamata di UnescapeDataString. – bmm6o

risposta

3

Ci sono alcune cose che mi cambia:

  • surrond i corsi d'acqua con il utilizzo della parola chiave using.
  • Utilizzare invece un gestore ashx. Sembra che tu stia usando un file aspx. Per questo tipo di scenari è meglio utilizzare un gestore HTTP, poiché ha un ciclo di vita più piccolo. L'ho usato molte volte per servire miniature di immagini.
  • Utilizzare un po 'di cache. Forse puoi sfruttare le funzionalità della cache di asp.net, puoi scoprire se ci sono valori ripetuti per t, quindi archiviare l'immagine risultante sulla cache ed evitare la scrittura e la creazione di alcuni flussi ogni volta
  • Ultimo ma non meno importante , prova a controllare se il server ha la sp e gli aggiornamenti più recenti. Ci sono alcuni casi in cui l'app si comporterà stranamente se ci sono determinati aggiornamenti mancanti,

Inoltre potrebbe essere associato alla web farm stessa. È possibile rivedere i contatori delle prestazioni del server per verificare se è presente qualche anomalia.

Spero che aiuti.

1

Si potrebbe risparmiare un po 'di memoria e, eventualmente, ottenere prestazioni salvando direttamente nel flusso di output invece di utilizzare un flusso di memoria:

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

Un altro problema potrebbe essere che il codice è nella pagina aspx. Potrebbe essere ricompilato troppo spesso. Vorrei suggerire un gestore http: