- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在构建一个将运行 BackgroundService
的 .NET Core 3.1 应用程序在 Docker 容器中。虽然我已经为 BackgroundService 实现了启动和关闭任务,并且在通过 SIGTERM
触发时服务肯定会关闭。 ,我发现 await host.RunAsync()
调用永远不会完成 - 意味着我的 Main()
中的剩余代码块没有被执行。
我是否遗漏了什么或者我不应该期待 RunAsync()
后台服务完成停止后调用返回控制?
(更新了我能想到的最简单的复制品......)
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace BackgroundServiceTest
{
class Program
{
static async Task Main(string[] args)
{
Console.WriteLine("Main: starting");
try
{
using var host = CreateHostBuilder(args).Build();
Console.WriteLine("Main: Waiting for RunAsync to complete");
await host.RunAsync();
Console.WriteLine("Main: RunAsync has completed");
}
finally
{
Console.WriteLine("Main: stopping");
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseConsoleLifetime()
.ConfigureServices((hostContext, services) =>
{
services.AddHostedService<Worker>();
// give the service 120 seconds to shut down gracefully before whacking it forcefully
services.Configure<HostOptions>(options => options.ShutdownTimeout = TimeSpan.FromSeconds(120));
});
}
class Worker : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
Console.WriteLine("Worker: ExecuteAsync called...");
try
{
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
Console.WriteLine("Worker: ExecuteAsync is still running...");
}
}
catch (OperationCanceledException) // will get thrown if TaskDelay() gets cancelled by stoppingToken
{
Console.WriteLine("Worker: OperationCanceledException caught...");
}
finally
{
Console.WriteLine("Worker: ExecuteAsync is terminating...");
}
}
public override Task StartAsync(CancellationToken cancellationToken)
{
Console.WriteLine("Worker: StartAsync called...");
return base.StartAsync(cancellationToken);
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
Console.WriteLine("Worker: StopAsync called...");
await base.StopAsync(cancellationToken);
}
public override void Dispose()
{
Console.WriteLine("Worker: Dispose called...");
base.Dispose();
}
}
}
Dockerfile:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["BackgroundServiceTest.csproj", "./"]
RUN dotnet restore "BackgroundServiceTest.csproj"
COPY . .
WORKDIR "/src/"
RUN dotnet build "BackgroundServiceTest.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "BackgroundServiceTest.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "BackgroundServiceTest.dll"]
docker -compose.yml:
version: '3.4'
services:
backgroundservicetest:
image: ${DOCKER_REGISTRY-}backgroundservicetest
build:
context: .
dockerfile: Dockerfile
通过
docker-compose up --build
运行它然后在第二个窗口中运行
docker stop -t 90 backgroundservicetest_backgroundservicetest_1
控制台输出显示 Worker 已关闭并被释放,但应用程序(显然)在
RunAsync()
之前终止。返回。
Successfully built 3aa605d4798f
Successfully tagged backgroundservicetest:latest
Recreating backgroundservicetest_backgroundservicetest_1 ... done
Attaching to backgroundservicetest_backgroundservicetest_1
backgroundservicetest_1 | Main: starting
backgroundservicetest_1 | Main: Waiting for RunAsync to complete
backgroundservicetest_1 | Worker: StartAsync called...
backgroundservicetest_1 | Worker: ExecuteAsync called...
backgroundservicetest_1 | info: Microsoft.Hosting.Lifetime[0]
backgroundservicetest_1 | Application started. Press Ctrl+C to shut down.
backgroundservicetest_1 | info: Microsoft.Hosting.Lifetime[0]
backgroundservicetest_1 | Hosting environment: Production
backgroundservicetest_1 | info: Microsoft.Hosting.Lifetime[0]
backgroundservicetest_1 | Content root path: /app
backgroundservicetest_1 | Worker: ExecuteAsync is still running...
backgroundservicetest_1 | Worker: ExecuteAsync is still running...
backgroundservicetest_1 | info: Microsoft.Hosting.Lifetime[0]
backgroundservicetest_1 | Application is shutting down...
backgroundservicetest_1 | Worker: StopAsync called...
backgroundservicetest_1 | Worker: OperationCanceledException caught...
backgroundservicetest_1 | Worker: ExecuteAsync is terminating...
backgroundservicetest_1 | Worker: Dispose called...
backgroundservicetest_backgroundservicetest_1 exited with code 0
最佳答案
在 lengthy discussion on Github 之后,事实证明,一些小的重构解决了这个问题。简而言之,.RunAsync()
阻塞直到主机完成并释放主机实例,这(显然)终止了应用程序。
通过更改代码调用.StartAsync()
然后 await host.WaitForShutdownAsync()
, 控制返回到 Main()
正如预期的那样。最后一步是将主机配置在 finally
中。如图所示:
static async Task Main(string[] args)
{
Console.WriteLine("Main: starting");
IHost host = null;
try
{
host = CreateHostBuilder(args).Build();
Console.WriteLine("Main: Waiting for RunAsync to complete");
await host.StartAsync();
await host.WaitForShutdownAsync();
Console.WriteLine("Main: RunAsync has completed");
}
finally
{
Console.WriteLine("Main: stopping");
if (host is IAsyncDisposable d) await d.DisposeAsync();
}
}
关于c# - IHost.RunAsync() 永不返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64453235/
我第一次用 GWT.RunAsync 拆分了我的模块以更快地加载。但是一旦加载,我想加载所有其他代码拆分,因为用户将空闲一段时间,并且在需要时他可以更快地处理这些部分。 有人尝试过这样做吗?有什么简单
我正在构建一个将运行 BackgroundService 的 .NET Core 3.1 应用程序在 Docker 容器中。虽然我已经为 BackgroundService 实现了启动和关闭任务,并且
我有一个具有invoke方法的函数,该函数在内部调用soap API, 而且执行过程大约需要22秒,代码中几乎没有其他方法, 因此,完全deleteSoemthing()(下面的代码)方法大约需要24
我正在尝试使用 CompletableFuture 在 JavaFX Canvas 上写入大量像素,尽管没有抛出异常,但我的方法似乎并未完成其任务。 我是异步编程的新手,不确定应该从哪里开始,但我认为
上下文:我已阅读 this SO 线程讨论 CompletableFuture 和 Thread 之间的差异。 但我试图了解何时应该使用 new Thread() 而不是 runAsync()。 我知
早上好, 我还没有完全掌握 CompletableFutures 的窍门(我是一位经验丰富的开发人员,但我并不觉得它们特别直观!)。 给出以下代码片段: public CompletionStage
我正在尝试在初始化不同子系统时使用 runAsync 来修改应用程序的加载性能,但我有几个问题: 当callback的onSuccess方法中调用的代码被拆分到另一个下载片段中时,被调用的类、子类、方
我写了下面的代码 ExecutorService service = Executors.newFixedThreadPool(3); Runnable task = () -> { System.o
如何停止 RunAsync? CancellatioTokenSource cts = new CancellationTokenSource(); //I thought that it's mus
我在网上搜索过关于ThreadHelper.JoinableTaskFactory.RunAsync的信息很少 如果我有以下代码,Test1 在 MainThread 上运行: public bool
我的代码运行良好: String name = "Oscar"; CompletableFuture.runAsync(() -> doX(name)); 现在我需要向 name 变量添加一些逻辑:
先决条件(一般描述): 1.静态类字段 static List ids = new ArrayList<>(); 2. CompletableFuture#runAsync(Runnable runn
我刚刚读了the documentation关于 CompletableFuture::runAsync 并且被解释弄糊涂了。这是那里写的: Returns a new CompletableFutu
我是 C# 的新手,目前正在做一个需要 BackgroundWorkers 的项目.我发现 BackgroundWorker RunWorkerAsync只需将一个对象作为参数。但在某些情况下,我需要
我有一组在 SQLite 异步方法中运行的 INSERT 语句: SQLite3JS.openAsync(path).then(function (db) { $.each(sql, func
我尝试使用 Kotlin 和 TornadoFX 库中的套接字连接来实现聊天应用程序以制作 GUI。 当我尝试启动客户端时出现问题,因为它一直在等待来自服务器的消息,尽管我将更新标签并接收消息的代码放
我的要求是每 30 秒轮询一次 MongoDB,以了解集合中的任何数据更改。我已使用 Java CompletableFuture.runAsync 来实现此功能,如下面捕获的代码所示。我已经测试运行
我正在使用 Dispatcher.RunAsync() 从后台线程显示 MessageDialog。但我无法弄清楚如何返回结果。 我的代码: bool response = f
假设我有这个示例代码,并且在 runAsync 中遇到异常。我的问题是这个异常是否会阻止 thenRun 被执行,因为 thenRun 与此代码的调用者方法在同一线程中运行。 private void
在等待 Dispatcher.RunAsync 时,继续会在工作安排时发生,而不是在工作完成时发生。我如何等待工作完成? 编辑 我最初的问题假设过早继续是由 API 的设计引起的,所以这是真正的问题。
我是一名优秀的程序员,十分优秀!