2014-01-29 138 views
10

我的一位同事寫了一些代碼,在進行web服務調用以檢查值的狀態之前,本質上暫停了1秒。此代碼寫入MVC 4應用程序的控制器操作中。操作本身不是異步的。在MVC控制器動作中暫停

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

它似乎工作,但由於某種原因,我對它的實施有一些擔憂。有沒有更好的方法來做這個延遲?

注:

  1. 我們沒有使用.NET 4.5和在此解決方案
  2. 的Javascript紙條選項,如SignalR不會改變這個目前不

我有一個選項他認爲這個問題是一個很好的選擇,但他沒有接受,並表示這不是他所做的工作所必需的。

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

+0

我會切換到ajax查詢網站,而不是阻塞在服務器上的線程25秒... – Timmerz

+0

是的,我會建議,感謝但時間可能是決定這一個。乾杯 – dreza

+0

可能已經使用.Net 4.5,但我仍然會提到這個和Thread.Sleep的風險是什麼。在線程不做任何事情但不能被分配來處理另一個請求的過程中,兩者都阻塞線程一段時間。這會導致在某些時候阻止HTTP請求,因爲沒有線程可用。當這一點取決於許多因素時,併發用戶的數量只是其中的一個,例如,每個用戶操作有許多ajax請求的站點將耗盡併發用戶較少的線程。所以不要阻塞線程,特別是在Web服務器上。 – user3285954

回答

26

對於MVC和你的情況,這已經足夠:

System.Threading.Thread.Sleep(1000); 

一個奇特的方式做同樣的事情,但有更多的開銷:

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

更新:

快速骯髒的性能測試:

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

我看到了很多評論,說這是有點不,即使用線程睡眠? – dreza

+0

如果你必須阻止服務器我認爲這個選項是最好的方式去...否則如我在其他評論中提到的,使用Ajax或其他東西,以避免鎖定網絡線程 – Timmerz

+1

如果你真的想等待1秒鐘,這是最簡單的方法。它將導致您正在運行此線程的唯一真正傷害將被阻止1秒。如果你想避免這種情況,請創建一個計時器,將Interval設置爲1000,並在Elapsed事件中執行任何你需要做的事情,但這可能不會起作用,因爲我認爲你需要將數據返回給客戶端。 – Fayilt