长时间运行的 ASP.NET MVC 核心控制器 HTTPPost 方法超时

Posted

技术标签:

【中文标题】长时间运行的 ASP.NET MVC 核心控制器 HTTPPost 方法超时【英文标题】:Timeouts with long running ASP.NET MVC Core Controller HTTPPost Method 【发布时间】:2016-09-25 06:03:04 【问题描述】:

我在我的ASP.NET Core MVC 视图页面中使用 ajax 调用

MyView.cshtml

          $.ajax(
                processData: false,
                contentType: false,
                data: new FormData(this),
                type: $(this).attr('method'),
                url: $(this).attr('action'),
                cache: false,
                success: function (data) 
                        $('#mydiv).html(data);
                        $('#bootstrapModal).modal('show');

Controller Post 方法"

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> MyLongRunningMethod(MyViewModel viewModel)
    
        await MyProcess.Longprocess1();
        await MyProcess.Longprocess2();
        await MyProcess.Longprocess3();
        await MyProcess.Longprocess4();
        return PartialView("_MyPartialPage");
    

这可行,但仅在长时间运行的过程中存在问题。当进程花费超过 2 分钟左右时,我在调试模式下收到以下错误

我知道这与过期超时有关

在以前版本的 ASP.NET MVC 中,您显然可以增加您的 asp.net 控制器操作的超时时间。

HttpContext.Current.Server.ScriptTimeout = 90000;

但是 ASP.NET Core 中不存在此功能

我想增加特定 asp.net 控制器的调试和部署超时时间。

对于生产,我可以通过将 requestTimeout 添加到现有的 httpPlatform 标记来在 web.config 中全局设置它。 例如10分钟

<httpPlatform requestTimeout="00:10:00" ....

有人问了一个类似的问题,但answer 使用CancellationToken 给出但阅读它,它似乎不能帮助我解决超时问题。

    如何像部署 Visual Studio 2015 调试模式一样设置超时? 是否有像 ASP.NET 4 中那样的每个控制器超时设置?

【问题讨论】:

VS 调试模式的变化如下所述。 ***.com/questions/49172284/… 【参考方案1】:

aspNetCore 标签上设置RequestTimeout="00:20:00" 并部署站点将导致它不会超时。

问题现在仅在从 Visual Studio 调试模式运行时出现,而不是在发布模式下。

注意:在 ASP.NET RTM 中,httpPlatform 标记已被替换为 aspNetCore 中的 web.config

ASP.NET Core 示例
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
    </handlers>
    <aspNetCore requestTimeout="00:20:00"  processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" forwardWindowsAuthToken="false"/>
  </system.webServer>
</configuration>

【讨论】:

这会在您按 F5 时导致 502 错误网关 现在使用 .net core 1.1,这似乎工作了! @firste 你找到调试模式的解决方案了吗?? 如果您在 Visual Studio 中运行,请尝试在控制台模式而不是 IIS 中运行。您应该会在显示 IIS 的下拉列表中看到与您的解决方案名称同名的选项,并且此选项似乎没有超时限制。 也适用于 2.0【参考方案2】:

但在 .Net Core 2.0 中,项目中没有 web.config 文件。它会自动生成。

我通过将.UseKestrel(...) 添加到Program.cs 文件中的BuildWebHost 函数来解决问题,如下所示:

public static IWebHost BuildWebHost(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .UseKestrel(o =>  o.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(10); )
        .Build();

【讨论】:

这将是最好的答案,因为默认情况下 web.config 不在项目中。 这并没有解决我的问题,我仍然得到 502 错误,可能是因为 web.config 存在于项目中 你有2.0的项目吗? 当您使用“dotnet publish”发布应用程序时,它会生成 web.config,以便您可以修改它 它也适用于我。谢谢【参考方案3】:

在我的情况下,即使在更新 requestTimeout 参数后,我们仍然在 2 分钟时出现 502 超时错误。事实证明,红隼有 2 分钟的保持活动超时,需要被覆盖:

var host = new WebHostBuilder()
               .UseKestrel(o =>
                    
                        o.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(30);
                    
                )

【讨论】:

“KestrelServerOptions”不包含“限制”的定义。这不是 ASP.NET Core 1.0 解决方案。 似乎存在于2.2中【参考方案4】:

自 .Net Core 3.1 以来,接受的答案发生了变化。在 NET Core 3.1 中使用以下实现来增加 KeepAliveTimeout:

程序.cs

public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            
                webBuilder.UseStartup<Startup>();
                webBuilder.ConfigureKestrel(options =>
                
                    options.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(15);
                );
            );

Web.Config(如果项目不存在,则需要将配置文件添加到项目中。)

根据 web.config 的要求增加 requestTimeout:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.webServer>
    <handlers>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified"/>
    </handlers>
    <aspNetCore requestTimeout="00:15:00"  processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
  </system.webServer>
</configuration>

【讨论】:

谢谢 - 只是确认一下:这是一个 AND 还是一个 OR,即两者都做还是其中之一? @toy 我必须同时做这两件事才能让它正常工作。【参考方案5】:

对我来说这很有效:

public static void Main(string[] args)

    CreateWebHostBuilder(args).Build().Run();


public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
    WebHost.CreateDefaultBuilder(args)
        .UseStartup<Startup>()
        .ConfigureKestrel(o =>  o.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(10); );

【讨论】:

【参考方案6】:

在 Visual Studio 中,解决方案探索中不会出现文件 web.config。我修复了在解决方案中添加文件并更改了属性“复制到输出目录”。

【讨论】:

以上是关于长时间运行的 ASP.NET MVC 核心控制器 HTTPPost 方法超时的主要内容,如果未能解决你的问题,请参考以下文章

在 ASP.Net MVC5 中管理长时间运行的进程

部署在 IIS 上的 ASP.NET Core 对长时间运行的请求返回 502 错误

将控制台应用程序的标准输出流式传输到 ASP.NET MVC 视图

ASP.NET Web API + 长时间运行的操作取消

使用长时间运行的方法阻止 ASP.NET Web 窗体中的网页

如何异步运行长时间运行的操作并在 ASP.Net Ajax 中为用户显示加载并轮询结果?