我试图理解为什么我的示例项目中的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 和调试输出:
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
答案 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包:
<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调用并再次测试。
修改强>
我提供了相同的代码,但我无法重现这种行为
我的结果如预期。
我试图将睡眠毫秒数改为1000 - 都是一样的
即使添加Debug.WriteLine也没有效果。
也许您在处理器核心负载不足时测试了网站?
答案 3 :(得分:0)
尝试使用Task.Delay()而不是Thread.Sleep()