为什么异步await不能在IIS上运行,但它正在使用IIS Express [英] Why async await doesn't working on IIS, but it's working on IIS Express

查看:217
本文介绍了为什么异步await不能在IIS上运行,但它正在使用IIS Express的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不明白,为什么async / await不能解决IIS线程的问题。

I don't understand, why async/await doesn't resolve problem with IIS threads.

我看到我们对IIS线程的限制等于10,当我使用IIS并且IIS表达没有限制时。

我在HomeController中添加了2个方法来重复此问题。其中一个(方法)使用Thread.Sleep和其他使用async / await。

I add 2 methods in HomeController for repeat this problem. One of them (method) use Thread.Sleep and other use async/await.

当然我使用logger(NLog)来更详细地描述这个问题。

Of course I use logger (NLog) for describe this problem in more details.

我使用apache-jmeter-3.0对100个并行请求进行压力测试。

I use apache-jmeter-3.0 with 100 parallel request for one url as stress test.

I当IIS的测试执行时间大致相同而且IIS快递的测试执行时间大致相同时,我感到很惊讶。

HomeController的一些代码

Some code from HomeController

[SessionState(SessionStateBehavior.Disabled)]
public class HomeController : Controller
{
    private const int _waitTimeout = 30000;
    private const string _beginFmt = "Begin method; Count = {0}; OperId = {1};";
    private const string _endFmt =   "End method  ; Count = {0}; OperId = {1};";

    private static volatile int _counter = 0;
    private static Logger _logger = LogManager.GetCurrentClassLogger();

    public JsonResult GetWithThreadSleep()
    {
        Guid operId = Guid.NewGuid();

        _logger.Info(_beginFmt, Interlocked.Increment(ref _counter), operId);

        Thread.Sleep(_waitTimeout);

        _logger.Info(_endFmt, Interlocked.Decrement(ref _counter), operId);

        return Json(null, JsonRequestBehavior.AllowGet);
    }

    public async Task<JsonResult> GetWithTaskAwait()
    {
        Guid operId = Guid.NewGuid();

        _logger.Info(_beginFmt, Interlocked.Increment(ref _counter), operId);

        await Task.Delay(_waitTimeout);

        _logger.Info(_endFmt, Interlocked.Decrement(ref _counter), operId);

        return Json(null, JsonRequestBehavior.AllowGet);
    }
}

日志格式

    <target xsi:type="File" 
            name="f" fileName="${basedir}/logs/${shortdate}.log"
            layout="${threadid} @ ${date:format=HH\:mm\:ss} @ ${level} @${aspnet-sessionid} @ ${message} @ ${callsite:className=False}" 
    />

测试场景一:我向方法 GetWithTaskAwait 并期望处理的速度超过 5分钟,因为线程应该重复使用。

Test scenario one: I send 100 parallel GET request to method GetWithTaskAwait and expect that the requests will be processed faster than 5 minutes, because thread should reused.

但事实并非如此。测试持续时间等于5分钟

But this is not the case. Test duration equals 5 minutes

1 @ 23:43:54 @ Info @ @ MVC Count = 1; @ .ctor
1 @ 23:43:54 @ Info @ @ APP Count = 1; @ Application_Start
11 @ 23:44:06 @ Info @ @ MVC Count = 2; @ .ctor
...
13 @ 23:45:36 @ Info @ @ End method  ; Count = 8; OperId = 28818fba-5535-4c01-9d6d-5efa3943cf37; @ MoveNext
19 @ 23:45:36 @ Info @ @ Begin method; Count = 9; OperId = c3cd3339-ec29-4625-adb9-62d5c72831b0; @ GetWithTaskAwait
12 @ 23:45:36 @ Info @ @ End method  ; Count = 9; OperId = d1686c05-ca7a-400c-8c17-43dfb7b9218a; @ MoveNext
16 @ 23:45:36 @ Info @ @ Begin method; Count = 10; OperId = c1ec5517-649c-4733-9db3-e666e648abae; @ GetWithTaskAwait
13 @ 23:45:36 @ Info @ @ End method  ; Count = 9; OperId = fbcfc9d9-fb84-456b-82a1-a0d593ef0815; @ MoveNext
...
26 @ 23:49:06 @ Info @ @ End method  ; Count = 8; OperId = 766d4bc5-3739-4e20-a242-1f114dd44442; @ MoveNext
22 @ 23:49:06 @ Info @ @ End method  ; Count = 7; OperId = 0ba18b30-11c9-49fe-8c94-40bbfa817e88; @ MoveNext
16 @ 23:49:06 @ Info @ @ End method  ; Count = 9; OperId = 6d7afd57-6128-4bee-bf32-92de7cfc6a34; @ MoveNext
26 @ 23:49:06 @ Info @ @ End method  ; Count = 6; OperId = 4c022744-9932-4f94-be1d-b982e36460f2; @ MoveNext
22 @ 23:49:06 @ Info @ @ End method  ; Count = 5; OperId = 05476e6a-106f-4da5-b99b-098b90dbab89; @ MoveNext
16 @ 23:49:07 @ Info @ @ End method  ; Count = 4; OperId = 3aba1ad2-56b0-4cf5-8aee-7e918eca9fba; @ MoveNext
27 @ 23:49:07 @ Info @ @ End method  ; Count = 3; OperId = ef972cdd-7992-4816-9452-ecabaf189767; @ MoveNext
15 @ 23:49:07 @ Info @ @ End method  ; Count = 2; OperId = 9a0f735e-bf6b-4217-b2ef-8abd9ce01d27; @ MoveNext
30 @ 23:49:07 @ Info @ @ End method  ; Count = 0; OperId = cc75b44a-4e8d-4534-9906-40bddc027267; @ MoveNext
33 @ 23:49:07 @ Info @ @ End method  ; Count = 1; OperId = bbef36b3-051b-444d-858a-2766bcfcd12b; @ MoveNext
...
26 @ 23:49:49 @ Info @ @ MVC Count = 10; @ Dispose
30 @ 23:50:19 @ Info @ @ MVC Count = 9; @ Dispose
16 @ 23:50:49 @ Info @ @ MVC Count = 8; @ Dispose

测试场景二:我向方法发送100个并行GET请求 GetWithThreadSleep 并预计请求将被处理相等 5分钟,因为线程不应重复使用。

Test scenario two: I send 100 parallel GET request to method GetWithThreadSleep and expect that the requests will be processed equal 5 minutes, because thread shouldn't reuse.

1 @ 00:15:41 @ Info @ @ MVC Count = 1; @ .ctor
1 @ 00:15:41 @ Info @ @ APP Count = 1; @ Application_Start
11 @ 00:16:14 @ Info @ @ MVC Count = 2; @ .ctor
...
15 @ 00:16:15 @ Info @ @ Begin method; Count = 8; OperId = cedb5075-405c-4c23-93cb-388dc34537ba; @ GetWithThreadSleep
17 @ 00:16:15 @ Info @ @ MVC Count = 10; @ .ctor
17 @ 00:16:15 @ Info @ @ Begin method; Count = 9; OperId = 777d7464-f900-48c1-991f-ef8c8f7e6e86; @ GetWithThreadSleep
18 @ 00:16:16 @ Info @ @ MVC Count = 11; @ .ctor
18 @ 00:16:16 @ Info @ @ Begin method; Count = 10; OperId = f9b4b717-94a5-4196-958f-c1234d19514c; @ GetWithThreadSleep
12 @ 00:16:45 @ Info @ @ End method  ; Count = 8; OperId = 9e40acd4-888f-4656-a5a3-c5a1d210cc88; @ GetWithThreadSleep
5 @ 00:16:45 @ Info @ @ End method  ; Count = 9; OperId = b068e03e-37e9-446e-ad42-c9ab4c30da93; @ GetWithThreadSleep
11 @ 00:16:45 @ Info @ @ End method  ; Count = 7; OperId = 22e510e5-62f7-4bc8-8ab0-fdeb3080e250; @ GetWithThreadSleep
...
18 @ 00:21:15 @ Info @ @ End method  ; Count = 2; OperId = 169ef436-6b27-4f4c-a3ca-0b18a5a796cf; @ GetWithThreadSleep
13 @ 00:21:16 @ Info @cubgm2zsojblkhrwwpixaaej @ End method  ; Count = 1; OperId = ee346be8-17c5-45ac-88b5-67e724250bbf; @ GetWithThreadSleep
12 @ 00:21:16 @ Info @ @ End method  ; Count = 0; OperId = 68d5deaa-95d6-4627-a129-144ffafcc2ef; @ GetWithThreadSleep
13 @ 00:22:11 @ Info @ @ MVC Count = 10; @ Dispose
9 @ 00:22:41 @ Info @ @ MVC Count = 9; @ Dispose

重要信息:


  • IIS版本10.0.14393.0

  • .NET Framework 4.5.1

  • Windows 10 Pro

您可以从 GitHub下载完整的解决方案

推荐答案

桌面操作系统上的IIS(Win 7/8/10)会将您的请求限制为10个并发。

IIS on a desktop OS (Win 7/8/10) will limit your requests to 10 concurrent.

在服务器操作系统(2008/2012/2016)上,该限制不存在。

On server OS's (2008/2012/2016), that limit does not exist.

在IIS Express上限制也不存在。

On IIS Express that limit also does not exists.

此限制的原因是您不会在桌面操作系统上使用IIS进行生产。

The reason for this limit is so you won't use IIS on a desktop OS for production purposes.

https:// weblogs。 asp.net/owscott/windows-8-iis-8-concurrent-requests-limit

这篇关于为什么异步await不能在IIS上运行,但它正在使用IIS Express的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆