在没有计时器的情况下保持 Windows 服务运行

问题描述 投票:0回答:2

目前我见过的 C# 中 Windows 服务的唯一示例是计时器每 x 秒运行一次方法 - 例如检查文件更改。

我想知道是否有可能(如果可能的话,使用示例代码)在没有计时器的情况下保持 Windows 服务运行,而只是让服务侦听事件 - 就像控制台应用程序仍然可以侦听事件并避免关闭一样

Console.ReadLine()
,无需计时器。

我本质上是在寻找一种方法来避免事件发生和执行操作之间有x秒的延迟。

c# windows service timer
2个回答
8
投票

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();
    }
}

这些都不需要计时器


0
投票
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}");

        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.