使用 IIS 时 CancellationToken 不触发
CancellationToken not Triggering when using IIS
我知道像这样的问题已经被问过很多次了,但是 none 提供的答案解决了我的特殊问题。所以我再试一次,自己问一个问题。
我正在开发 ASP.NET 核心 Web 应用程序 运行ning net461
(也尝试过 net48
),我在其中定义了这样的 HTTP 端点:
[HttpGet]
[Route("query/{queryName}")]
public async Task<IActionResult> Call(string queryName, CancellationToken cancellationToken)
{
await Task.Delay(5_000, cancellationToken);
...
}
如标题所述,我无法在浏览器端启动刷新时让 cancellationToken
触发 TaskCanceledException
,而初始请求仍在处理中(Chrome devtools 将这些事件显示为已取消的请求)。我让它工作的唯一方法是在 Visual Studio 的调试设置中选择 "Project"(见下面的屏幕截图),我猜这会使整个应用程序 运行 仅在 Kestrel 中 -前面没有任何反向代理。
我遇到了各种 post,声称此问题将通过 ASP.NET Core 2.2 解决,其中 in-process 托管应与 CancellationToken
结合使用。所以我更新了我所有的 nuget 包,但不幸的是没有效果,错误仍然存在。是的,我在本地使用 IIS Express 进行调试,我不确定这与常规 IIS 设置究竟有何不同,但我也在 Azure 上 运行ning 这个应用程序,整个过程看起来就像是运行ning in-process,因为只有一个进程运行ning(见下面的截图)。
这是我安装的 AspNetCore 软件包的 csproj 的摘录:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.13.1" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Server.IIS" Version="2.2.6" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
</Project>
我也尝试过 Program.cs,因为我怀疑这可能是另一个潜在的错误来源。我尝试使用 UseIIS()
扩展方法仅强制执行 in-process 托管,但对 CancellationToken
:
也没有明显影响
public class Program
{
public static void Main(string[] args)
{
var host = WebHost.CreateDefaultBuilder(args)
//.UseKestrel()
.UseIIS()
.UseContentRoot(Directory.GetCurrentDirectory())
//.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
host.Run();
}
}
我的问题:
CancellationToken
是否仅适用于 netcoreapp2.x
(或更高版本)作为目标框架?
- 这是配置问题吗(Program.cs、Startup.cs、csproj 等)?
- 我可以 运行 在 Windows 上的 Azure Web 应用服务上仅使用 Kestrel 时使用此应用程序吗?如果是,我该如何配置?
- 还有什么我可能遗漏的吗?
长话短说:原来 Azure 应用服务使用的是 7 级负载均衡器,它不会将连接关闭事件转发到 Web 应用程序。因此,无论您是在 IIS 上使用 Kestrel 还是进程内托管的 Web 应用程序,您的应用程序都不会收到通知。
显而易见的解决方案是在应用程序级别自行处理此类事件。通过设置 KeepAliveInterval
(WebSockets) 或使用 SignalR 直接订阅连接关闭事件。
我知道像这样的问题已经被问过很多次了,但是 none 提供的答案解决了我的特殊问题。所以我再试一次,自己问一个问题。
我正在开发 ASP.NET 核心 Web 应用程序 运行ning net461
(也尝试过 net48
),我在其中定义了这样的 HTTP 端点:
[HttpGet]
[Route("query/{queryName}")]
public async Task<IActionResult> Call(string queryName, CancellationToken cancellationToken)
{
await Task.Delay(5_000, cancellationToken);
...
}
如标题所述,我无法在浏览器端启动刷新时让 cancellationToken
触发 TaskCanceledException
,而初始请求仍在处理中(Chrome devtools 将这些事件显示为已取消的请求)。我让它工作的唯一方法是在 Visual Studio 的调试设置中选择 "Project"(见下面的屏幕截图),我猜这会使整个应用程序 运行 仅在 Kestrel 中 -前面没有任何反向代理。
我遇到了各种 post,声称此问题将通过 ASP.NET Core 2.2 解决,其中 in-process 托管应与 CancellationToken
结合使用。所以我更新了我所有的 nuget 包,但不幸的是没有效果,错误仍然存在。是的,我在本地使用 IIS Express 进行调试,我不确定这与常规 IIS 设置究竟有何不同,但我也在 Azure 上 运行ning 这个应用程序,整个过程看起来就像是运行ning in-process,因为只有一个进程运行ning(见下面的截图)。
这是我安装的 AspNetCore 软件包的 csproj 的摘录:
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.13.1" />
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Server.IIS" Version="2.2.6" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="2.2.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
</Project>
我也尝试过 Program.cs,因为我怀疑这可能是另一个潜在的错误来源。我尝试使用 UseIIS()
扩展方法仅强制执行 in-process 托管,但对 CancellationToken
:
public class Program
{
public static void Main(string[] args)
{
var host = WebHost.CreateDefaultBuilder(args)
//.UseKestrel()
.UseIIS()
.UseContentRoot(Directory.GetCurrentDirectory())
//.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();
host.Run();
}
}
我的问题:
CancellationToken
是否仅适用于netcoreapp2.x
(或更高版本)作为目标框架?- 这是配置问题吗(Program.cs、Startup.cs、csproj 等)?
- 我可以 运行 在 Windows 上的 Azure Web 应用服务上仅使用 Kestrel 时使用此应用程序吗?如果是,我该如何配置?
- 还有什么我可能遗漏的吗?
长话短说:原来 Azure 应用服务使用的是 7 级负载均衡器,它不会将连接关闭事件转发到 Web 应用程序。因此,无论您是在 IIS 上使用 Kestrel 还是进程内托管的 Web 应用程序,您的应用程序都不会收到通知。
显而易见的解决方案是在应用程序级别自行处理此类事件。通过设置 KeepAliveInterval
(WebSockets) 或使用 SignalR 直接订阅连接关闭事件。