3

Currently the only examples of a Windows service in C# I have seen are where a timer runs through a method every x seconds - e.g. checking for file changes.

I'm wondering if it is possible (with example code if possible) to keep a Windows service running without a timer and instead just have a service listening for events - in the same way a console application can still listen for events and avoid closing with Console.ReadLine() without requiring a timer.

I am essentially looking for a way to avoid the x second delay between an event happening and an action being performed.

  • what type of service are you wanting to create there are many ways to keep a console open and running without closing using a while loop for example but you should provide more information in regards to what type of service you are wanting to run.. also why are you trying to avoid using timers..? – MethodMan Mar 11 '15 at 21:29
  • 1
    Windows service is not much different than a winforms app. So if it is a console, winforms app or windows service, The idea is the same, – EZI Mar 11 '15 at 21:35
  • It depends on what you want to accomplish. In most cases, when no timer is involved, a WCF service is developed - [see this question for more info on WCF services](http://stackoverflow.com/questions/1773046/gui-and-windows-service-communication) – bokibeg Mar 11 '15 at 21:36
  • @bokibeg `In most cases, when no timer is involved, a WCF service is developed` You must be kidding.... – EZI Mar 11 '15 at 21:37
  • @EZI I'm not, if he wants to "listen to events", I'm assuming these events would come from another app in which case named pipes would be used and that's best done via WCF. – bokibeg Mar 11 '15 at 21:39
  • @bokibeg `if he wants to "listen to events",` Yes, for example to use a FileSystemWatcher, would you use named pipe? WCF? or any other *remoting* thing? You don't know what you're talking about. – EZI Mar 11 '15 at 21:41
  • @EZI You are right, "in most cases" was quite a bad choice of words I admit. I said that under assumption that only intent was event based communication with other apps. – bokibeg Mar 11 '15 at 21:52

1 Answers1

8

A windows service does not need to create a timer to keep running. It can either establish a file watcher Using FileSystemWatcher to monitor a directory or start an asynchronous socket listener.

Here is a simple TPL based listener/responder without needing to dedicate a thread to the process.

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

Neither of these need a timer

Community
  • 1
  • 1
John Taylor
  • 446
  • 3
  • 8