2015-11-14 29 views
2

我想了解爲什麼我的示例項目中的nancyFx無法處理並行查詢。 我運行Windows 8,VS2015,C#,小提琴手4.NancyFx自託管休息服務無法處理並行查詢

這裏是我的示例服務:

class Program 
    { 
     static void Main(string[] args) 
     { 
      Listen(); 
     } 

     static void Listen() 
     { 
      using (var host = new NancyHost(new Uri("http://localhost:4546"))) 
      { 
       host.Start(); 
       Console.ReadLine(); 
      } 
     } 
    } 

    public class TestModule : NancyModule 
    { 
     public TestModule() : base("/") 
     { 
      Get["/"] = (param) => 
      { 
       Debug.WriteLine("Start:" + DateTime.Now.TimeOfDay.ToString()); 
       Thread.Sleep(100); 
       Debug.WriteLine("End:" + DateTime.Now.TimeOfDay.ToString()); 
       return Response.AsText("Success"); 
      }; 
     } 
    } 

下面是示例查詢:

GET http://localhost:4546/ HTTP/1.1 
Accept: text/html, application/xhtml+xml, */* 
Accept-Language: ru-RU 
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; Trident/7.0; rv:11.0) like Gecko 
Accept-Encoding: gzip, deflate 
Host: localhost:4546 
Connection: Keep-Alive 

我已經使用小提琴手4並行查詢生成(重放功能)和度量查詢運行時間。

當我運行一個查詢 - 處理時間約爲100毫秒(0:00:00.104), 但是當我運行多個查詢 - 處理時間長太多了,這裏是例子: Fiddler parallel queries screenshot enter image description here 和調試輸出:

Start:09:56:32.8385200 
Start:09:56:32.8443855 
End:09:56:32.9396601 
End:09:56:32.9455256 
Start:09:56:32.9465022 
End:09:56:33.0478691 
Start:09:56:33.0478691 
End:09:56:33.1498256 
Start:09:56:33.1507976 
End:09:56:33.2516390 
Start:09:56:33.2535998 
End:09:56:33.3554522 
Start:09:56:33.3564277 
End:09:56:33.4584340 
Start:09:56:33.4594080 
End:09:56:33.5608216 
Start:09:56:33.5617992 
End:09:56:33.6631615 
Start:09:56:33.6641370 
End:09:56:33.7649969 
Start:09:56:33.7659714 
End:09:56:33.8673301 
Start:09:56:33.8683072 
End:09:56:33.9696905 
Start:09:56:33.9706676 
End:09:56:34.0713212 
Start:09:56:34.0722972 
End:09:56:34.1729940 
Start:09:56:34.1759211 
End:09:56:34.2774876 

正如我們在fiddler時間線中可以看到的 - 所有查詢在同一時間開始運行,但執行時間不同。

此外,我們可以用不同的有效載荷和行爲替換Thread.Sleep仍然相同。

此外,我們可以用RestSharp,HttpClient替換用於查詢生成的fiddler - 行爲仍然相同。

此外,我們可以用ServiceStack.Server(也是自託管的)替換NancyFx - 行爲仍然相同。

爲什麼? :)我怎麼能解決它?

UPD: 此外,通過@ FireAlkazar的猜測,我試圖刪除Debug.WriteLine的。

現在的代碼是:

Get["/"] = (param) => { 
    var response = Response.AsText(""); 
    Thread.Sleep(100); 
    return response; 
}; 

和結果一樣,這裏是截圖:here is it

+0

P.S.當它被IIS託管時,所有查詢都並行運行。但它會消耗更多的內存 - 所以,我仍然想解決自我託管問題。 – Dmitriy

回答

0

我想這是Debug.WriteLine調用導致出現此問題。
寫在多線程環境控制檯將鎖的線程類同代碼

lock(globalStaticObject) 
{ 
    Print("some message") 
} 

嘗試再次刪除的Debug.WriteLine調用和測試。

編輯
我有你提供的相同的代碼,我不能再現行爲。
我的結果與預期一致。 enter image description here
我試圖將睡眠毫秒數改爲1000 - 都一樣。
即使添加Debug.WriteLine也沒有你有的效果。
也許您在處理器內核處於負載下時測試了該站點?

+1

不,它沒有得到任何影響:現在的代碼是: 'Get [「/」] =(param)=> { var response = Response.AsText(「」); Thread.Sleep(100); 返回響應; };' 和結果一樣,這裏是截圖:[here is it](http://s012.radikal.ru/i319/1511/1b/c103062886b3.png) – Dmitriy

+0

@Dmitriy真的很奇怪。將嘗試重現並深入調查。 – FireAlkazar

+0

@Dmitriy看到我的編輯。我無法重現這種行爲。 – FireAlkazar

1

你們有沒有試過使方法異步?真正的參數告訴Nancy作爲async運行,而async關鍵字告訴VS內部的代碼將返回一個Task或者擁有一個await關鍵字...注意:我沒有測試過這段代碼,因爲我正在使用它有點複雜的方法,但它應該運行。

Get["/", true] = async (param, ct) => { 
    var response = Response.AsText(""); 
    Thread.Sleep(100); 
    return Task.FromResult<string>(response); 
};