当前位置: 首页 > news >正文

承德建设网站wordpress+discuz+seo

承德建设网站,wordpress+discuz+seo,产品研发,网站使用mip后效果怎么样在这篇文章中#xff0c;我们将了解 .NET 8 中为托管服务引入的一些新生命周期事件。请注意#xff0c;这篇文章与 .NET 8 相关#xff0c;在撰写本文时#xff0c;.NET 8 目前处于预览状态。在 11 月 .NET 8 最终版本发布之前#xff0c;类型和实现可能会发生变化。要继续…        在这篇文章中我们将了解 .NET 8 中为托管服务引入的一些新生命周期事件。请注意这篇文章与 .NET 8 相关在撰写本文时.NET 8 目前处于预览状态。在 11 月 .NET 8 最终版本发布之前类型和实现可能会发生变化。要继续操作您将需要.NET 8Announcing .NET 8 - .NET Blog。 IHostedLifecycleService 简介 主要更改是在 Microsoft.Extensions.Hosting 命名空间中包含一个名为 IHostedLifecycleService 的新接口。此接口继承自现有的 IHostedService 接口对其进行扩展以添加在现有 StartAsync 和 StopAsync 方法之前或之后发生的新生命周期事件的方法。这些提供了一种方法来挂钩某些高级场景的更具体的应用程序生命周期事件。 接口定义如下 public partial interface IHostedLifecycleService : Microsoft.Extensions.Hosting.IHostedService {Task StartingAsync(CancellationToken cancellationToken);Task StartedAsync(CancellationToken cancellationToken);Task StoppingAsync(CancellationToken cancellationToken);Task StoppedAsync(CancellationToken cancellationToken); } 实现此接口的所有已注册托管服务的 StartAsync 方法将在应用程序生命周期的早期运行然后在任何已注册托管服务上调用 StartAsync来自 IHostedService。这可用于在应用程序启动之前执行一些非常早期的验证检查例如检查关键需求或可用的依赖项。这使得应用程序可能在任何托管服务开始执行其主要工作负载之前启动失败。其他用途包括“预热”和初始化单例以及应用程序使用的其他状态。 注册托管服务的所有 StartAsync来自 IHostedService方法完成后将在实现上调用 StartedAsync。这可用于在将应用程序标记为成功启动之前验证应用程序状态或条件。 StoppingAsync 和 StoppedAsync 在应用程序关闭期间的工作方式类似并为关闭前和关闭后验证提供高级挂钩。 在讨论更详细的细节之前值得讨论一下为什么 Microsoft 创建了一个新的派生接口而不是利用默认接口实现来更新现有的 IHostedService 接口。对于默认接口实现来说这确实是一个很好的例子可以将它们添加到具有默认无操作实现的 IHostedService 中。当我们查看该库的运行时目标时原因很明显。托管包多目标各种目标框架。这包括netstandard2.0它在引入默认接口实现功能之前就被锁定了。因此为了继续支持这个目标改用衍生的接口设计。 作为引入此接口的 PR 的一部分HostOptions 中还添加了一个新选项 StartupTimeout。这允许提供一个 TimeSpan 来控制所有托管服务启动所允许的最长时间。当配置为非无限值默认值时传递给启动生命周期事件的取消令牌将链接到使用提供的值配置的 CancellationTokenSource。 使用新界面         使用 .NET 8 我们可以查看如何使用此新界面的一般示例。我在应用程序中看到的一项相当常见的启动工作是初始化数据库。 在生产过程中我们可以预期此类数据库是在线的、可用的和种子的在其他环境中例如 CI我们可能需要创建一个虚拟数据库并使用示例数据进行播种。存在多种解决方案来处理此问题但一种可能的选择是使用托管服务有条件地执行工作。当其他托管服务依赖于可用数据库时这可能会更加复杂因为这些服务必须在数据库准备就绪后以正确的顺序启动。在 .NET 7 中这是可以实现的因为托管服务按顺序并按照注册顺序启动。 因此在 .NET 7 中我们可以实现以下目标 public class ServiceA : IHostedService {public Task StartAsync(CancellationToken cancellationToken){// INIT DBreturn Task.CompletedTask;}public Task StopAsync(CancellationToken cancellationToken) Task.CompletedTask; }public class ServiceB : BackgroundService {protected override Task ExecuteAsync(CancellationToken stoppingToken){// USE DBreturn Task.CompletedTask;} } 为了向 DI 容器注册这些服务以便主机执行它们我们必须确保以正确的顺序专门添加它们。 builder.Services.AddHostedServiceServiceA(); builder.Services.AddHostedServiceServiceB(); 由于 .NET 7 按顺序而不是同时执行每个服务的 StartAsync 方法因此我们知道在调用 ServiceB.StartAsync 时数据库应该已在 ServiceA 中完成初始化。 虽然默认情况下在 .NET 8 中也是如此但现在也可以配置主机以同时启动它们。如果我们想更改此选项我们的应用程序可能会崩溃因为 ServiceB 会与 ServiceA 同时触发。这可能不是一个重要问题但如果应用程序中有其他托管服务通过切换到并发执行我们可以减少应用程序的整体启动时间。 通过在 .NET 8 中引入新的 IHostedLifecycleService我们可以将数据库初始化工作移至生命周期的早期同时还可以利用并发托管服务启动。 public class ServiceA : IHostedService, IHostedLifecycleService {public Task StartingAsync(CancellationToken cancellationToken){// INIT DBreturn Task.CompletedTask;}public Task StartAsync(CancellationToken cancellationToken) Task.CompletedTask;public Task StartedAsync(CancellationToken cancellationToken) Task.CompletedTask;public Task StoppingAsync(CancellationToken cancellationToken) Task.CompletedTask;public Task StopAsync(CancellationToken cancellationToken) Task.CompletedTask;public Task StoppedAsync(CancellationToken cancellationToken) Task.CompletedTask; }public class ServiceB : BackgroundService {protected override Task ExecuteAsync(CancellationToken stoppingToken){// USE DBreturn Task.CompletedTask;} } 在上面的示例代码中我们定义了两个托管服务。除了 IHostedService 之外ServiceA 还实现了新的 IHostedLifecycleService。我们希望在应用程序生命周期的早期、任何主要工作负载之前执行数据库初始化。因此我们可以将数据库设置代码包含在 GettingAsync 方法中。 派生自BackgroundService 的ServiceB 现在可以在其ExecuteAsync 方法内安全地使用数据库因为ExecuteAsync 是由IHostedService 接口中定义的StartAsync 的底层实现调用的。因此在注册服务的所有 StartingAsync 方法完成之前不会调用它。 我们将以与 .NET 中相同的方式向 DI 容器注册这些服务但添加它们的顺序不再重要。 builder.Services.AddHostedServiceServiceB(); builder.Services.AddHostedServiceServiceA(); 即使按照这个顺序ServiceA的StartingAsync也会在ServiceB.StartAsync之前执行。我们甚至可以配置并发启动和停止行为而不会破坏我们的逻辑。 builder.Services.ConfigureHostOptions(options { options.ServicesStartConcurrently true; options.ServicesStopConcurrently true; }); 深入细节 引入新接口后最核心的更改是在内部 Host 类内部实现的该类实现了 IHost 接口。此类定义了主 Host在从 ASP.NET Core 和 Worker Service 等模板创建新应用程序时构建。IHost 接口定义了当应用程序启动或停止时调用的 StartAsync 和 StopAsync 方法。 第一个有意义的更改在 StartAsync 方法的开头引入了额外的逻辑以实现新的StartupTimeout 功能。 CancellationTokenSource? cts null; CancellationTokenSource linkedCts; if (_options.StartupTimeout ! Timeout.InfiniteTimeSpan) {cts new CancellationTokenSource(_options.StartupTimeout);linkedCts CancellationTokenSource.CreateLinkedTokenSource(cts.Token, cancellationToken, _applicationLifetime.ApplicationStopping); } else {linkedCts CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, _applicationLifetime.ApplicationStopping); } 从更新后的代码中我们可以看到在所有情况下传递到 StartAsync 的取消令牌都可能导致取消就像 IHostApplicationLifetime 上公开的 ApplicationStopping 令牌一样如果触发关闭该令牌将被标记为已取消。 当 HostOptions.StartupTimeout 不等于 InfiniteTimeSpan 时将创建 CancellationTokenSource并将 TimeSpan 传递到构造函数中。然后可以将其令牌添加到链接的令牌源以确保第三个条件也可以触发中止启动。这个新选项允许应用程序开发人员为预期的“正常”启动提供预期的上限时间这样在特殊情况下长时间的延迟就可以主动触发启动的中止。这种情况可能是由不可用的外部依赖项引起的应进行跟踪和记录以便进行调查。 创建 linkedCts 后它将用于访问 CancellationToken然后将其传递到启动过程中调用的任何后续异步方法中。 CancellationToken token linkedCts.Token; 第一个异步方法是 IHostLifetime.WaitForStartAsync 的调用这是托管生命周期中的早期挂钩此时正在等待。这是另一个高级挂钩可能会延迟启动直到收到外部事件信号为止。这个概念从 .NET Core 3.0 开始就已经存在。 // This may not catch exceptions. await _hostLifetime.WaitForStartAsync(token).ConfigureAwait(false);         token.ThrowIfCancellationRequested(); 实现中的下一行准备一些变量和字段。 ListException exceptions new(); _hostedServices Services.GetRequiredServiceIEnumerableIHostedService(); _hostedLifecycleServices GetHostLifecycles(_hostedServices); bool concurrent _options.ServicesStartConcurrently; bool abortOnFirstException !concurrent; 设置列表以包含启动期间的任何异常后将从容器中检索所有已注册的 IHostedService。GetHostLifecycles 方法用于循环 IHostedService 实现并确定哪个如果有也实现 IHostedLifecycleService。 下一段代码为每个 IHostedLifecycleService 执行 GettingAsync 方法。 if (_hostedLifecycleServices is not null) {// Call StartingAsync().await ForeachService(_hostedLifecycleServices, token, concurrent, abortOnFirstException, exceptions,(service, token) service.StartingAsync(token)).ConfigureAwait(false); } ForeachService 是一个辅助方法它根据作为参数传入的 HostOptions 设置并发或顺序执行服务。 private static async Task ForeachServiceT(IEnumerableT services,CancellationToken token,bool concurrent,bool abortOnFirstException,ListException exceptions,FuncT, CancellationToken, Task operation) {if (concurrent){// The beginning synchronous portions of the implementations are run serially in registration order for// performance since it is common to return Task.Completed as a noop.// Any subsequent asynchronous portions are grouped together run concurrently.ListTask? tasks null;foreach (T service in services){Task task;try{task operation(service, token);}catch (Exception ex){exceptions.Add(ex); // Log exception from sync method.continue;}if (task.IsCompleted){if (task.Exception is not null){exceptions.AddRange(task.Exception.InnerExceptions); // Log exception from async method.}}else{tasks ?? new();tasks.Add(Task.Run(() task, token));}}if (tasks is not null){Task groupedTasks Task.WhenAll(tasks);try{await groupedTasks.ConfigureAwait(false);}catch (Exception ex){exceptions.AddRange(groupedTasks.Exception?.InnerExceptions ?? new[] { ex }.AsEnumerable());}}}else{foreach (T service in services){try{await operation(service, token).ConfigureAwait(false);}catch (Exception ex){exceptions.Add(ex);if (abortOnFirstException){return;}}}} } 代码基于布尔并发参数进行分支。让我们重点关注用于同时调用每个服务的功能的代码。 正如注释所述实现首先在每个服务上调用操作委托在本例中为“StartingAsync”。许多 IHostedLifecycleService 完全有可能通过返回缓存的 Task.CompletedTask 在其大多数方法上实现无操作。在这些情况下代码同步运行因为没有什么可等待的。上面的代码对此进行了特殊处理并检查是否有任何任务立即返回完成或抛出同步异常。对于这些已完成的任务其中引发的任何异常都会添加到异常列表中。 对于此时尚未完成的任何任务它们都是异步运行的。这些任务将添加到任务列表中。所有任务启动后就会使用 WhenAll 等待它们这意味着它们会同时运行直到所有注册的服务都完成其工作。任何异常也会在这里捕获。 在非并发路径中代码更简单因为它可以简单地按顺序等待每个操作。在此配置中每个服务必须在调用下一个服务之前完成其工作。 返回 Host.StartAsync 方法对 IHostedService.StartAsync 和 IHostedLifecycleService.StartedAsync 重复该过程。该方法最后会记录并重新抛出任何捕获的异常然后触发托管应用程序现已启动的通知。 Stopping 和 Stopped 的新生命周期事件的实现几乎相同因此我们无需在这里深入讨论。 概括         Microsoft 在每个版本中不断完善和增强 .NET 中的托管概念。在 .NET 8 中重点放在引入对托管服务的启动行为的更多控制。在这项最新的工作中他们引入了对启动和关闭之前、期间和之后运行的代码的高级、细粒度控制。新的 IHostedLifecycleService 接口出现在.NET 8 中现已推出。
http://www.hkea.cn/news/14285000/

相关文章:

  • 浙江金顶建设公司网站会员卡管理系统怎么开通
  • 怎么做教育网站做网站关键词要懂代码么
  • 易语言如何做网站中信建设有限责任公司ppp项目管理部
  • 网站现状如何分析拉新app推广平台排名
  • 网站建设工作室wp主题模板抓取网站后台密码
  • 福永网站推广网站重新建设的通知
  • 廊坊网站建设公司网站建设流程包括哪些内容
  • 测量为什么要建站嘉兴网站建设企业
  • 网站优化排名分享隐迅推北京房产网站大全
  • 化工建网站多少费用网站开发培训班多少报名费
  • 网站主页特效欣赏wordpress 模版安装
  • 企业网站的一般要素吉安好的网站建设公司
  • 亿唐网不做网站做品牌考试题湛江网站排名
  • 电商网站数据中心建设方案asp网站上传到服务器上之后一打开就是download
  • 做的好的排版网站建购物网站
  • oss可以做网站根目录吗甘肃网站建设域名注册公司
  • 地方网站做相亲赢利点在哪里绵阳建设局网站皱劲松
  • 个人备案网站名称怎么写南宁哪些公司专业做网站
  • 网站备案怎么取消小众网站论文
  • 兰州网站建设与优化推广wordpress优秀免费主题
  • 网站建设后台是怎么制作的邯郸模板建站教程
  • 手机网站 win8风格百度竞价排名公司
  • 北京网站优化托管数据统计网站有哪些
  • 网站内容更改教程wap网站建设服务
  • 做网站.服务器怎么买小语种网站开发
  • 网站小图标素材建网站 收费标准
  • 做网站避免上当小程序登录代码
  • 建湖做网站多少钱网站需要多少钱
  • 怎样将自己做的网页加入网站东莞58同城
  • 零基础网站开发要学多久建筑网片多少钱一平方