我想在 ASPNET Core 中实现一个可以按需停止和启动的循环(定时)IHostedService 实例。我的理解是 IHostedService(s) 是在应用程序启动时由框架启动的。
但是,我希望能够“手动”启动/停止服务,或许可以通过 UI 使用开/关切换。理想情况下,“关闭”状态将处理当前正在运行的服务,而“开启”状态将创建一个新实例。
我在这里阅读了 MS 文档:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.1 .
我最初的想法是获取正在运行的服务的实例,然后调用公共(public) StopAsync(CancellationToken token)方法。但是,当涉及到我应该传入哪个 token 时,我有点卡住了,对于 StartAsync(CancellationToken cancellationToken) 也是如此。方法。
关于应该如何完成的任何想法,或者它是否可取?我的方法是否以某种方式违背了 ASPNET Core 中托管服务的预期设计?
编辑 2018 年 7 月 27 日
因此,经过更多研究(也就是阅读文档 :D)托管服务 StartAsync/StopAsync 方法确实与应用程序的生命周期一致。注册的 IHostedServices 似乎没有添加到 DI 容器中以注入(inject)其他类。
因此我认为我最初的想法不会奏效。现在,我使用可以在运行时更新的配置依赖项 ( IOptions<T>) 注册了我的服务。当托管服务正在处理时,它将检查配置以查看它是否应该继续,否则它将只是等待(而不是停止或处置托管服务)。
除非我听到其他想法,否则我可能很快会将其标记为我的答案。
最佳答案
对于 StopAsync(CancellationToken token),您可以传递 new System.Threading.CancellationToken()。在 public CancellationToken(bool cancelled) 的定义中,canceled 表示 token 的状态。对于您的方案,无需指定 canceled 因为您要停止服务。
您可以按照以下步骤进行操作:
创建IHostedService
public class RecureHostedService : IHostedService, IDisposable
{
private readonly ILogger _log;
private Timer _timer;
public RecureHostedService(ILogger<RecureHostedService> log)
{
_log = log;
}
public void Dispose()
{
_timer.Dispose();
}
public Task StartAsync(CancellationToken cancellationToken)
{
_log.LogInformation("RecureHostedService is Starting");
_timer = new Timer(DoWork,null,TimeSpan.Zero, TimeSpan.FromSeconds(5));
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
_log.LogInformation("RecureHostedService is Stopping");
_timer?.Change(Timeout.Infinite, 0);
return Task.CompletedTask;
}
private void DoWork(object state)
{
_log.LogInformation("Timed Background Service is working.");
}
}
注册IHostedService
services.AddSingleton<IHostedService, RecureHostedService>();
启动和停止服务
public class HomeController : Controller {
private readonly RecureHostedService _recureHostedService;
public HomeController(IHostedService hostedService)
{
_recureHostedService = hostedService as RecureHostedService;
}
public IActionResult About()
{
ViewData["Message"] = "Your application description page.";
_recureHostedService.StopAsync(new System.Threading.CancellationToken());
return View();
}
public IActionResult Contact()
{
ViewData["Message"] = "Your contact page.";
_recureHostedService.StartAsync(new System.Threading.CancellationToken());
return View();
} }
关于c# - ASP.NET Core IHostedService 手动启动/停止/暂停(?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51469881/
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
require'mechanize'agent=Mechanize.newlogin=agent.get('http://www.schoolnet.ch/DE/HomeDE.htm')agent.clicklogin.link_withtext:/Login/然后我得到Mechanize::UnsupportedSchemeError。 最佳答案 Mechanize不支持javascript但您可以将搜索字段添加到表单并为其分配搜索词并使用mechanize提交表单form=page.forms.firstform.add_fie
我仍然收到标题中的“错误”消息,但不知道如何解决。在ApplicationController中,classApplicationController在routes.rb#match'set_activity_account/:id/:value'=>'users#account_activity',:as=>:set_activity_account--thisdoesn'tworkaswell..resources:usersdomemberdoget:action_a,:action_bendcollectiondoget'account_activity'endend和User
我正在使用rubydaemongem。想知道如何向停止操作添加一些额外的步骤?希望我能检测到停止被调用,并向其添加一些额外的代码。任何人都知道我如何才能做到这一点? 最佳答案 查看守护程序gem代码,它似乎没有用于此目的的明显扩展点。但是,我想知道(在守护进程中)您是否可以捕获守护进程在发生“停止”时发送的KILL/TERM信号...?trap("TERM")do#executeyourextracodehereend或者你可以安装一个at_exit钩子(Hook):-at_exitdo#executeyourextracodehe
我想用Capistrano启动sidekiq。下面是代码namespace:sidekiqdotask:startdorun"cd#{current_path}&&bundleexecsidekiq-c10-eproduction-Llog/sidekiq.log&"pcapture("psaux|grepsidekiq|awk'{print$2}'|sed-n1p").strip!endend它执行成功但sidekiq仍然没有在服务器上启动。输出:$capsidekiq:starttriggeringloadcallbacks*2014-06-0315:03:01executing`
我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume