【问题标题】:How to make an ASP.NET app to be single threaded如何使 ASP.NET 应用程序成为单线程
【发布时间】:2022-08-19 08:18:09
【问题描述】:

我试图强制一个 asp.net 应用程序是单线程的,即:一次只能服务一个请求(需要这样做来模拟遗留应用程序)。

我能想到的只是使用一个静态变量来锁定和 Monitor.TryEnter 并让线程休眠 5 秒钟以模拟只有一个线程处理请求。

有没有更好/优雅的方法来强制asp.net应用程序仅是单线程的,即:一次只能严格处理一个请求。

这将作为 Docker 容器运行,Kestrel 为请求提供服务。

到目前为止,这似乎是可行的,当调用 /test 端点时,它会阻塞整个应用程序 5 秒

public class Program
{
    private static readonly object LockObject = new();

    public static void Main(string[] args)
    {
        var builder = WebApplication.CreateBuilder(args);

        // Add services to the container.
        builder.Services.AddAuthorization();

        builder.Services.AddEndpointsApiExplorer();
        builder.Services.AddSwaggerGen();

        builder.Services.AddApplicationInsightsTelemetry();


        var app = builder.Build();

        // Configure the HTTP request pipeline.
        if (app.Environment.IsDevelopment())
        {
            app.UseSwagger();
            app.UseSwaggerUI();
        }

        app.UseAuthorization();

        app.MapGet(\"/test\", (HttpContext httpContext) =>
        {
            if (Monitor.TryEnter(LockObject, new TimeSpan(0, 0, 6)))
            {
                try
                {
                    Thread.Sleep(5000);
                }
                finally
                {
                    Monitor.Exit(LockObject);
                }
            }

            return (\"Hello From Container: \" + System.Environment.MachineName);
        });

        app.Run();
    }
}
  • 您的目标是一次只接受一个连接,还是一次只处理一个请求?
  • @DiplomacyNotWar 理想情况下,一次只接受一个连接,不确定 Kestrel 是否可行,所以下一个最好的办法是一次处理一个请求。此应用程序将托管在一个容器中,因此 Kestrel 将为该应用程序提供服务
  • 得去吃晚饭了,但也许看看这个属性的红隼:docs.microsoft.com/en-us/dotnet/api/…
  • 您可以使用并发限制器中间件nuget.org/packages/Microsoft.AspNetCore.ConcurrencyLimiter
  • 我要说的是,您可以使用 async SemaphoreSlim 轻松构建自己的中间件,以在不阻塞线程的情况下限制并发。但这足以实现您想要的吗?

标签: c# asp.net .net asp.net-core single-threaded


【解决方案1】:

如果您的应用程序托管在 iis 上
在应用程序中选择了应用程序池

点击高级设置
选项队列长度:1

https://docs.revenera.com/installshield23helplib/helplibrary/IIS-AppPoolsNode.htm

如果您从 iis express 运行

可以使用 applicationHost.config 文件配置 IIS Express。它位于 %userprofile%\my documents\IISexpress\config

看看这个帖子Configure Maximum Number of Requests in IIS Express

在红隼

builder.WebHost.ConfigureKestrel(serverOptions =>
{
   serverOptions.Limits.MaxConcurrentConnections = 1;
});

【讨论】:

  • 这假定应用程序托管在 IIS 上。您可能应该用 OP 澄清这一点。
  • 谢谢你,很高兴知道在 IIS 中这很容易实现。我已经更新了我的问题,这将作为 Docker 容器运行,因此 Kestrel 将是默认设置,想知道 Kestrel 中是否有类似的控件?
【解决方案2】:

您可以使用ConcurrencyLimiter 中间件来限制并发请求。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-11
    相关资源
    最近更新 更多