使用定期任务在 C# 中构建 Windows 服务 [重复]
Posted
技术标签:
【中文标题】使用定期任务在 C# 中构建 Windows 服务 [重复]【英文标题】:Building Windows Service in C# with periodic task [duplicate] 【发布时间】:2021-02-08 13:50:30 【问题描述】:我想用 C# 构建一个 Windows 服务。
此服务需要每隔 10 秒定期运行一次。
问题:
Timers.timer 和 Threading.timer 有什么区别?
如何调用带参数的 CheckingThings?
如果我运行此代码,它会像此处声明的那样每秒多次调用 CheckingThings:
_timer = new Timer(new TimerCallback(CheckingThings), autoEvent, 5000, 1000);
这是我目前得到的:
public partial class WindowsService1 : ServiceBase
// Logging
private static Serilog.Core.Logger _logEvent;
public WindowsService1()
InitializeComponent();
public void OnDebug()
OnStart(null);
protected override void OnStart(string[] args)
//Logging
try
_logEvent = new LoggerConfiguration()
.WriteTo.File(AppDomain.CurrentDomain.BaseDirectory + @"Logs\Logfile.txt", rollingInterval: RollingInterval.Month)
.CreateLogger();
catch (Exception e)
_logEvent.Error("The logging service is not working as expected: errorMsg", e);
try
// initializing some data here
var autoEvent = new AutoResetEvent(true);
while (true)
_timer = new Timer(new TimerCallback(CheckingThings), autoEvent, 5000, 1000);
catch (Exception e)
_logEvent.Error("An error occured while initializing service: 0", e);
private static void CheckingThings(object stateInfo)
AutoResetEvent autoEvent = (AutoResetEvent)stateInfo;
//These things needs to run periodically every 10s
protected override void OnStop()
_logEvent.Information("Stopping Service ...");
【问题讨论】:
您的第一个问题已经在这里得到解答:***.com/questions/1416803/… 你似乎创建了无限数量的计时器while (true) _timer = new Timer(new TimerCallback(CheckingThings), autoEvent, 5000, 1000);
如果我删除 while 循环它只运行一次
您想构建 Windows 服务还是定期运行它?
我如何使用参数调用 CheckingThings? - 如果您对计时器说“这里,每 10 秒调用一次此方法并提供各种参数”,您如何期待计时器知道要提供哪些参数?您如何期望手机的早上 8 点闹钟会打开您的咖啡机?您希望它如何拨入您上午 10 点会议的会议号码和 PIN 码? (提示;它不会 - 它只是提醒您当前时间,因此您必须执行这些操作)
【参考方案1】:
这是一个每分钟执行一些操作的服务类的框架,使用 System.Timers.Timer
:
public partial class XService : ServiceBase
private Timer _minute = new Timer(60000);
public XService()
InitializeComponent();
_minute.Elapsed += Minute_Elapsed;
//this is async because my 'stuff' is async
private async void Minute_Elapsed(object sender, ElapsedEventArgs e)
_minute.Stop();
try
//stuff
catch (Exception ex)
//log ?
finally
_minute.Start();
protected override void OnStart(string[] args)
_minute.Start(); //this or..
Minute_Elapsed(null, null); //..this, if you want to do the things as soon as the service starts (otherwise the first tick will be a minute after start is called
...
我通常会在我做我的事情时停止我的计时器 - 开始一项需要 10 分钟然后一分钟后再做一次的工作是没有意义的,因此停止/尝试/最终/开始模式
编辑:
这是课程的结尾部分,以及它是如何在调试(在 Visual Studio 内部)和发布(作为已安装的 Windows 服务)中启动/启动的:
//just an adapter method so we can call OnStart like the service manager does, in a debugging context
public void PubOnStop()
OnStop();
// end of XService class
static void Main(string[] args)
#if DEBUG
new XService().PubStart(args);
Thread.Sleep(Timeout.Infinite);
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
new XService()
;
ServiceBase.Run(ServicesToRun);
#endif
【讨论】:
非常感谢!!!如果我必须从 text/ini 文件中读取要检查的内容怎么办?有可能通过那些吗? Minute_Elapsed 中的代码实际上没有任何限制。好吧,除非您以无权访问本地磁盘资源的用户身份运行该服务...阅读您的 INI如果您不想停止并重新启动获取新设置的服务 我试过你的骨架,但它没有做循环计时器?! 呃.. 我直接将它从一个工作服务中提取出来,该服务每分钟都会检查它必须编码的视频。你是如何开始服务的? 这就是我启动服务的方式 backgroundTask = Task.Factory.StartNew(() => CheckingThings(cancellation), canceling, TaskCreationOptions.LongRunning, TaskScheduler.Default);背景任务.Wait(); while (!cancellation.IsCancellationRequested) // 主线程需要在那里工作以上是关于使用定期任务在 C# 中构建 Windows 服务 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
如何在基于 C# 的 Windows 服务中处理以不同时间间隔并行运行的多个任务?