目前我见过的 C# 中 Windows 服务的唯一示例是计时器每 x 秒运行一次方法 - 例如检查文件更改。
我想知道是否有可能(如果可能的话,使用示例代码)在没有计时器的情况下保持 Windows 服务运行,而只是让服务侦听事件 - 就像控制台应用程序仍然可以侦听事件并避免关闭一样
Console.ReadLine()
,无需计时器。
我本质上是在寻找一种方法来避免事件发生和执行操作之间有x秒的延迟。
Windows 服务不需要创建计时器来保持运行。它可以建立一个文件观察器使用 FileSystemWatcher 来监视目录或启动一个异步套接字侦听器。
这是一个简单的基于 TPL 的侦听器/响应程序,无需为进程专用线程。
private TcpListener _listener;
public void OnStart(CommandLineParser commandLine)
{
_listener = new TcpListener(IPAddress.Any, commandLine.Port);
_listener.Start();
Task.Run((Func<Task>) Listen);
}
private async Task Listen()
{
IMessageHandler handler = MessageHandler.Instance;
while (true)
{
var client = await _listener.AcceptTcpClientAsync().ConfigureAwait(false);
// Without the await here, the thread will run free
var task = ProcessMessage(client);
}
}
public void OnStop()
{
_listener.Stop();
}
public async Task ProcessMessage(TcpClient client)
{
try
{
using (var stream = client.GetStream())
{
var message = await SimpleMessage.DecodeAsync(stream);
_handler.MessageReceived(message);
}
}
catch (Exception e)
{
_handler.MessageError(e);
}
finally
{
(client as IDisposable).Dispose();
}
}
这些都不需要计时器
sing System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace WindowsServiceWithoutTimer
{
public partial class Service1 : ServiceBase
{
FileSystemWatcher fileSystemWatcher;
public static void WriteToFile(string Message)
{
string path = @"G:\Logs";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string filepath = @"G:\Logs\ServiceLog_" + DateTime.Now.Hour.ToString().Replace('/', '_') + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
if (!File.Exists(filepath))
{
using (StreamWriter sw = File.CreateText(filepath))
{
sw.WriteLine(Message);
}
}
else
{
using (StreamWriter sw = File.AppendText(filepath))
{
sw.WriteLine(Message);
}
}
}
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
fileSystemWatcher = new FileSystemWatcher();
fileSystemWatcher.Path = @"g:\test";
// Only watch text files
fileSystemWatcher.Filter = "*.txt";
// Add event handlers for the various events
fileSystemWatcher.Created += OnCreated;
fileSystemWatcher.Changed += OnChanged;
fileSystemWatcher.Deleted += OnDeleted;
fileSystemWatcher.Renamed += OnRenamed;
// Start watching the directory
fileSystemWatcher.EnableRaisingEvents = true;
}
protected override void OnStop()
{
// Stop watching the directory
fileSystemWatcher.EnableRaisingEvents = false;
}
private void OnCreated(object sender, FileSystemEventArgs e)
{
WriteToFile($"File created: {e.FullPath}");
}
private static void OnChanged(object sender, FileSystemEventArgs e)
{
WriteToFile($"File changed: { e.FullPath}");
}
private static void OnDeleted(object sender, FileSystemEventArgs e)
{
WriteToFile($"File deleted: {e.FullPath}");
}
private void OnRenamed(object sender, RenamedEventArgs e)
{
WriteToFile($"File renamed: {e.OldFullPath} -> {e.FullPath}");
}
}
}