2014-01-29 24 views
10

Ein Kollege von mir schrieb einen Code, der im Wesentlichen für eine Sekunde pausiert, bevor er einen Webservice-Aufruf tätigt, um den Status eines Werts zu überprüfen. Dieser Code wird in eine Controlleraktion einer MVC 4-Anwendung geschrieben. Die Aktion selbst ist nicht asynchron.Anhalten innerhalb einer MVC-Controlleraktion

var end = DateTime.Now.AddSeconds(25); 
var tLocation = genHelper.GetLocation(tid); 

while (!tLocation.IsFinished && DateTime.Compare(end, DateTime.Now) > 0) 
{ 
    var t = DateTime.Now.AddSeconds(1); 
    while (DateTime.Compare(t, DateTime.Now) > 0) continue; 

    // Make the webservice call so we can update the object which we are checking the status on 
    tLocation = genHelper.GetLocation(tid); 
} 

Es scheint aus irgendeinem Grund zu arbeiten, aber ich habe einige Bedenken darüber Umsetzung ist. Gibt es einen besseren Weg, diese Verzögerung zu machen?

HINWEIS:

  1. Wir nicht .NET 4.5 verwenden und wird diese nicht
  2. Javascript Scrip Optionen wie SignalR in dieser Lösung ändern sind keine Option derzeit

Ich hatte dachte, die Frage sei eine gute Option, aber er nahm es nicht auf und sagte, es sei nicht erforderlich, was er getan habe.

How to put a task to sleep (or delay) in C# 4.0?

+0

Ich würde Ajax wechseln die Website statt Blockieren des Thread auf dem Server 25 Sekunden abfragen ... – Timmerz

+0

Ja, werde ich diesen Dank empfehlen aber die Zeit könnte der Decider auf dieses. Prost – dreza

+0

Wahrscheinlich mit .Net 4.5 schon, aber ich würde immer noch erwähnen, was das Risiko von diesem und Thread.Sleep ist. Beide blockieren einen Thread für einen Zeitraum, während dessen der Thread nichts tut, aber er kann auch nicht zugewiesen werden, um eine andere Anfrage zu bedienen. Dies führt zu einem Blockieren von HTTP-Anfragen, da keine Threads verfügbar sind. Wenn dieser Punkt kommt, hängt von vielen - vielen Faktoren ab, und die Anzahl der gleichzeitigen Benutzer ist nur eine von ihnen, z. Eine Site mit vielen Ajax-Anfragen pro Benutzeraktionen wird ohne Threads mit weniger gleichzeitigen Benutzern auskommen. Blockiere also keine Threads, besonders auf einem Webserver. – user3285954

Antwort

26

für MVC und Ihre Situation ist dies ausreichend:

System.Threading.Thread.Sleep(1000); 

Eine andere Art, das Gleiche zu tun, sondern mit mehr Aufwand:

Task.WaitAll(Task.Delay(1000)); 

Update:

Schneller und schmutziger Leistungstest:

class Program 
{ 
    static void Main() 
    { 
     DateTime now = DateTime.Now; 

     for(int i = 0; i < 10; ++i) 
     { 
      Task.WaitAll(Task.Delay(1000)); 
     } 

     // result: 10012.57xx - 10013.57xx ms 
     Console.WriteLine(DateTime.Now.Subtract(now).TotalMilliseconds); 

     now = DateTime.Now; 

     for(int i = 0; i < 10; ++i) 
     { 
      Thread.Sleep(1000); 
     } 

     // result: *always* 10001.57xx 
     Console.WriteLine(DateTime.Now.Subtract(now).TotalMilliseconds); 

     Console.ReadLine(); 
    } 
} 
+0

Ich sah ein paar Kommentare zu sagen, dass dies ein bisschen nein war, das heißt mit Thread Schlaf? – dreza

+0

Wenn Sie auf dem Server blockieren müssen, denke ich, diese Option ist der beste Weg zu gehen ... andernfalls, wie ich in meinem anderen Kommentar erwähnte, verwenden Sie ajax oder etwas, um zu vermeiden, die Web-Threads – Timmerz

+1

zu sperren Wenn Sie wirklich warten wollen 1 Sekunde, das ist der einfachste Weg. Der einzige wirkliche Schaden, der dazu führt, dass der Thread, auf dem du diesen Thread ausführst, wird für 1 Sekunde blockiert. Wenn Sie das vermeiden wollen, erstellen Sie einen Timer, setzen Sie Interval auf 1000 und tun Sie alles, was Sie im Elapsed-Event tun müssen, aber das wird wahrscheinlich nicht funktionieren, da ich davon ausgehe, dass Sie die Daten an den Client zurückgeben müssen. – Fayilt