如何解决.NET通用主机-是否可以停止并重新启动主机?
考虑这个非常简单的.NET Core 3.1(和.NET 5)应用程序,没有特殊的配置或托管服务:
80090308: LdapErr: DSID-0C090446,comment: AcceptSecurityContext error,data 701,v2580
第一次运行(仅作为本次测试的目的,发送为后台启动并忘记了任务)和停止成功完成。再次调用Run时,我收到此异常:
System.AggregateException:'对象名称:'EventLogInternal'。无法访问已处置的对象。对象名称:“ EventLogInternal”。)
如果我执行相同的操作,但使用StartAsync而不是RunAsync(这次不需要fireAndForget),则第二次调用StartAsync时,我会收到using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
internal class Program
{
public static async Task Main(string[] args)
{
var builder = Host.CreateDefaultBuilder(args);
builder.UseWindowsService();
var host = builder.Build();
var fireAndforget = Task.Run(async () => await host.RunAsync());
await Task.Delay(5000);
await host.StopAsync();
await Task.Delay(5000);
await host.RunAsync();
}
。
我是否应该推断出.NET通用主机不是要停止并重新启动?
我为什么需要这个?
我的目标是让一个应用程序作为Windows服务运行,该应用程序将承载两个不同的.NET通用主机。这是基于here的建议,以便具有单独的配置和依赖项注入规则以及消息队列。
其中一个将在整个应用程序生命周期中保持活动状态(直到该服务在Windows服务中停止),并用作接收消息事件的入口点,该消息事件将启动/停止另一个事件,该事件将成为具有完整功能的主要处理主机。服务。这样,主服务可以一直处于“空闲”状态,直到它们接收到触发其进程的消息,而另一条消息则可以使它们返回空闲状态。
解决方法
由CreateDefaultBuilder(...).Build()
返回的主机旨在代表整个应用程序。来自docs:
将应用程序所有相互依赖的资源包含在一个对象中的主要原因是生命周期管理:控制应用程序的启动和正常关闭。
缺省构建器在单例范围内注册许多服务,并且当主机停止时,所有这些服务都将被处置或切换为某种“已停止”状态。例如,在致电StopAsync
之前,您可以解决IHostApplicationLifetime
:
var appLifetime = host.Services.GetService<IHostApplicationLifetime>();
它具有代表应用程序状态的取消令牌。停止后调用StartAsync或RunAsync时,所有令牌仍将IsCancellationRequested
设置为true
。这就是将OperactionCancelledException
抛出到Host.StartAsync中的原因。
对我来说,听起来您只需要一些后台作业即可处理消息,但是我从未使用过NServiceBus,所以我不知道它如何与Hangfire之类的东西一起工作。您还可以实现IHostedService
并在通用主机生成器中使用它。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。