NancyFx自托管的休息服务无法处理并行查询

时间:2015-11-14 07:02:17

标签: c# rest parallel-processing fiddler nancy

我试图理解为什么我的示例项目中的nancyFx无法处理并行查询。 我正在运行Windows 8,VS2015,C#,fiddler 4.

以下是我的示例服务:

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

我使用fiddler 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替换fiddler,HttpClient用于查询生成 - 行为仍然相同。

我们也可以用ServiceStack.Server(也是自托管)替换NancyFx - 行为仍然相同。

为什么呢? :)以及我如何解决它?

UPD: 另外,@ FireAlkazar猜测我已经尝试删除Debug.WriteLine了。

现在代码是:

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

结果相同,这里是截图:here is it

4 个答案:

答案 0 :(得分:1)

你们有没有试过让这些方法异步? true参数告诉Nancy以异步方式运行,async关键字告诉VS其中的代码将返回一个Task或者有一个await关键字...注意我没有测试过这段代码,因为我正在使用它比较复杂的方法,但它应该运行。

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

答案 1 :(得分:1)

Nancy.Hosting.Self中有一个bugfix来解决这个问题。但是,最新的预览NuGet包已有1.5年历史,并且不包含此修复程序。

您可以按照以下步骤修复错误,而无需更新NuGet包:

  • NancyHost.cs复制到您的项目中。
  • HostConfiguration.cs文件中的<body> <script> function sendForm(){ var username = document.getElementById("sessionUser").value; var password = document.getElementById("sessionPw").value; var param = {}; param['username'] = username; param['password'] = password; post('http://localhost:8080/processLogin', param ); } </script> <iframe id=menuFrame frameborder="0" style="overflow:hidden;" src=""></iframe> </body> MaximumConnectionCount属性复制到您的ProcessorThreadCount课程中。
  • 修复NancyHost代码以使用复制的属性,而不是NancyHost中的属性。
  • 使用您的HostConfiguration课程启动课程。

答案 2 :(得分:0)

我猜是Debug.WriteLine次调用导致了这种行为 在多线程环境中写入控制台将锁定与代码类似的线程

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

尝试删除Debug.WriteLine调用并再次测试。

修改
我提供了相同的代码,但我无法重现这种行为 我的结果如预期。 enter image description here
我试图将睡眠毫秒数改为1000 - 都是一样的 即使添加Debug.WriteLine也没有效果。
也许您在处理器核心负载不足时测试了网站?

答案 3 :(得分:0)

尝试使用Task.Delay()而不是Thread.Sleep()