如何使进程始终运行并在特定时间执行函数
本文关键字:定时间 执行 函数 运行 何使 进程 | 更新日期: 2023-09-27 17:50:35
我想做一个进程/系统,它应该一直处于运行状态,并在特定的时间段执行特定的功能。
例如,如果我想让系统每周发送一封电子邮件到一个特定的地址,那么我应该怎么做?
Running always: go for Windows service对于周期性的东西:使用计时器
所以有一个Windows服务,它维护一个定时器设置在所需的间隔触发,做任何你需要在那里。
你可以使用开源的Quartz。. NET调度器(http://www.quartz-scheduler.net/),它可以在指定的时间和间隔触发作业。我的建议是在Windows服务中托管调度程序作业。
这是我的例子,对于一些任务它是ok的。
public class Timer : IRegisteredObject
{
private Timer _timer;
public static void Start()
{
HostingEnvironment.RegisterObject(new Timer());
}
public Timer()
{
StartTimer();
}
private void StartTimer()
{
_timer = new Timer(BroadcastUptimeToClients, null, TimeSpan.FromSeconds(0), TimeSpan.FromMilliseconds(100));
}
private void BroadcastUptimeToClients(object state)
{
//some action
}
public void Stop(bool immediate)
{
//throw new System.NotImplementedException();
}
}
在Global.asax Timer.Start();
在你的情况下,我同意@ Arsen Mkrtchyan -使用操作系统调度程序。如果你想使用windows服务,下面是你的服务:
partial class MyService
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
private Timer _watcherTimer = new System.Timers.Timer();
private static Logger logger = LogManager.GetCurrentClassLogger();
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "MyService";
this._watcherTimer.Interval = 6000;
this._watcherTimer.Enabled = false;
this._watcherTimer.Elapsed += new System.Timers.ElapsedEventHandler(this.Timer_Tick);
}
#endregion
}
partial class MyService : ServiceBase
{
public MyService()
{
try
{
InitializeComponent();
}
catch (Exception e)
{
logger.Error("Error initializing service",e);
Stop();
}
}
protected override void OnStart(string[] args)
{
_watcherTimer.Enabled = true;
logger.Info("Service has started at " + DateTime.UtcNow.ToLongDateString());
}
protected override void OnStop()
{
logger.Info("Service has stopped at " + DateTime.UtcNow.ToLongDateString());
}
private void Timer_Tick(object sender, ElapsedEventArgs e)
{
logger.Info("Timer Tick");
}
}
安装程序:
[RunInstaller(true)]
public class WindowsServiceInstaller : Installer
{
/// <summary>
/// Public Constructor for WindowsServiceInstaller.
/// - Put all of your Initialization code here.
/// </summary>
public WindowsServiceInstaller()
{
var serviceProcessInstaller =
new ServiceProcessInstaller();
var serviceInstaller = new ServiceInstaller();
//# Service Account Information
serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
serviceProcessInstaller.Username = null;
serviceProcessInstaller.Password = null;
//# Service Information
serviceInstaller.DisplayName = "MY SERVICE DISPLAY NAME";
serviceInstaller.Description = "MY SERVICE DESCRIPTION";
serviceInstaller.StartType = ServiceStartMode.Automatic;
//# This must be identical to the WindowsService.ServiceBase name
//# set in the constructor of WindowsService.cs
serviceInstaller.ServiceName = "MyService";
Installers.Add(serviceProcessInstaller);
Installers.Add(serviceInstaller);
}
}
用.bat
运行static class Program
{
static void Main(string[] args)
{
if (args.Length > 0)
{
//Install service
if (args[0].Trim().ToLower() == "/i")
{ System.Configuration.Install.ManagedInstallerClass.InstallHelper(new[] { "/i", Assembly.GetExecutingAssembly().Location }); }
//Uninstall service
else if (args[0].Trim().ToLower() == "/u")
{ System.Configuration.Install.ManagedInstallerClass.InstallHelper(new[] { "/u", Assembly.GetExecutingAssembly().Location }); }
}
else
{
var servicesToRun = new ServiceBase[] { new MyService() };
ServiceBase.Run(servicesToRun);
}
}
}
install.bat
@ECHO OFF
REM Prevent changing current directory when run bat file as administrator on win7
@setlocal enableextensions
@cd /d "%~dp0"
REM The following directory is for .NET 4.0
set DOTNETFX4=%SystemRoot%'Microsoft.NET'Framework'v4.0.30319
set PATH=%PATH%;%DOTNETFX4%
echo Installing WindowsService...
echo "%CD%'WindowsService'Service'bin'Debug'Service.exe"
echo ---------------------------------------------------
InstallUtil /i "%CD%'WindowsService'Service'bin'Debug'Service.exe"
echo ---------------------------------------------------
echo Done.
set /p DUMMY=Hit ENTER to continue...
unistall.bat
@ECHO OFF
REM Prevent changing current directory when run bat file as administrator on win7
@setlocal enableextensions
@cd /d "%~dp0"
REM The following directory is for .NET 4.0
set DOTNETFX4=%SystemRoot%'Microsoft.NET'Framework'v4.0.30319
set PATH=%PATH%;%DOTNETFX4%
echo Installing WindowsService...
echo ---------------------------------------------------
InstallUtil /u "%CD%'WindowsService'Service'bin'Debug'Service.exe"
echo ---------------------------------------------------
echo Done.
set /p DUMMY=Hit ENTER to continue...
我的文件夹层次:
install.bat
uninstall.bat
service-project-folder
packages
project-folder
.sln file
通过使用ReactiveExtensions,您可以使用以下代码,如果您有兴趣做一些像打印到控制台一样简单的事情,就像您目前在这里的hold问题https://stackoverflow.com/questions/30473281/how-to-print-a-string-in-c-sharp-after-every-1-minute-using-timer。你可以通过NuGet添加Rx-Main来添加响应式扩展。
using System;
using System.Reactive.Linq;
namespace ConsoleApplicationExample
{
class Program
{
static void Main()
{
Observable.Interval(TimeSpan.FromMinutes(1))
.Subscribe(_ =>
{
Console.WriteLine(DateTime.Now.ToString());
});
Console.WriteLine(DateTime.Now.ToString());
Console.ReadLine();
}
}
}