2012-03-24 7 views
1

Ich entwickle einen Web-Service mit ASP.NET MVC3. Eine der Methoden der HTTP-API empfängt ein Bild vom Hauptteil einer POST-Anforderung und muss es zur weiteren Verarbeitung auf der Festplatte speichern. Der Beginn des Verfahrens ist wie folgt:ASP.NET (oder IIS?) Verhalten bei gleichzeitiger Anfragen

Stopwatch stopwatch = new Stopwatch(); 
stopwatch.Start(); 

Interlocked.Increment(ref _generateCount); 

byte[] fileBuffer; 
using (Stream inputStream = Request.InputStream) 
{ 
    if (inputStream.Length == 0) 
    { 
     Trace.WriteLine("Submitted file is empty", "Warning"); 
     inputStream.Close(); 
     Interlocked.Decrement(ref _generateCount); 
     return new HttpStatusCodeResult(400, "Content is empty"); 
    } 

    fileBuffer = new byte[inputStream.Length]; 
    inputStream.Read(fileBuffer, 0, (int)inputStream.Length); 
    inputStream.Close(); 
} 
stopwatch.Stop() 
... (storing the fileBuffer on disk & quite CPU intensive processing on the file) 

ich den Dienst in einer kleinen Azure Instanz bin Hosting.

Jetzt ist das seltsame Verhalten, das ich habe, wenn ich parallele Anfragen an den Dienst ausstelle. Nehmen wir an, ich stelle eine erste Anfrage, und eine zweite 5 Sekunden später. Wie Sie sehen, verwende ich eine Stoppuhr, um die Leistung zu überwachen. Für die erste Anfrage wird die ElapsedTime sehr klein sein (weniger als eine Sekunde), aber für die zweite wird sie normalerweise ca. 14 Sekunden!

Beachten Sie, dass die durchschnittliche Bearbeitungszeit für eine einzelne Anfrage ca. 25 Sekunden (und erreicht 40+, wenn mehrere Anfragen verarbeitet werden), so dass ich 14 Sekunden später meinen Eingabestream gelesen habe, obwohl die erste Anfrage noch nicht abgeschlossen ist.

Wie kann ich diese Verzögerung erklären?

Dank

Antwort

1

Wenn Ihr Endziel die Datei auf der Festplatte zu speichern, ist, warum Sie es im Speicher geladen werden? Sie könnten direkt in den Ausgabestream schreiben:

public ActionResult SomeAction() 
{ 
    var stopwatch = Stopwatch.StartNew(); 
    if (Request.InputStream.Length == 0) 
    { 
     return new HttpStatusCodeResult(400, "Content is empty"); 
    } 

    var filename = Server.MapPath("~/app_data/foo.dat"); 
    using (var output = System.IO.File.Create(filename)) 
    { 
     Request.InputStream.CopyTo(output); 
    } 
    stopwatch.Stop(); 

    ... 
} 

Beachten Sie auch, dass, wenn Sie zwei gleichzeitige Anforderungen ausgeben, die auf die gleiche Datei auf dem Server zu schreiben versuchen, könnten Sie beschädigte Daten oder Fehler, wie Sie nicht auf die schreiben gleiche Datei zur gleichen Zeit.

+0

Hallo, Ich habe den Stream im Speicher für Debug-Zwecke geladen, aber das Löschen des Streams direkt auf der Festplatte scheint in der Tat das Problem zu lösen. Wie würdest du den Unterschied erklären? Oder kommt es von meinem inputStream.Close(), das auf eine Synchronisierung von IIS warten würde? – ThomasWeiss

+0

Wenn ich log4net Protokollierung für Debugging-Zwecke verwende und die Protokollanweisungen in eine bestimmte Datei schreibe. Würden die parallelen HTTP-Anfragen diese Protokolldatei überschreiben? – teenup

+0

@teenup, nein die Datei wird nicht überschrieben, Nachrichten werden an sie angehängt. –

Verwandte Themen