2

I have a windows service to do the background process. This windows service will interact to asp.net website. The functionality is as below.

In my website 3 actions are there. User can choose the task (suppose three buttons are there). Then it will call the windows service. The rest of the operation is performed by windows service. User can log out from the website, but it will run the service in background. Once it is finished it will make corresponding changes in database. I need to know whether I can apply any design pattern to the windows service (factory, abstract factory etc.). I have read about different design patterns, but I am really confused about how this applied to a project. Currently I am writing the entire code in ‘OnStart’ and ‘OnStop’ events of windows service. Please guide me.

Thanks.

Dev
  • 309
  • 1
  • 8
  • 24
  • 1
    You're going to at least need to start off by creating some running thread in the OnStart method. Ideally, the OnStart method needs to be immediately finished. Otherwise, when you start the service, it will hang with the "Starting" message until it times out. It sounds like you may want to look into some basic service tutorials and post specific issues you're having. [This](http://stackoverflow.com/a/12886071/724591) is the basic use of a timer. – matth Jan 13 '14 at 14:46
  • thanks a lot for the reply. It was really useful. Currently I am creating multiple instance of service to handle multiple users who is logged into the website. Now I think instead of creating multiple service instance I can create a new thread for a request from another user..rt?(one service and multiple threads) And I can also restrict the number of new threads to be created. Is that a right approach? – Dev Jan 14 '14 at 04:32
  • and what about design pattern? My service logic contain some db operations and some static class with read only array. Is there any specific role for design pattern there? I am bit confused about its usage.--> Thanks. – Dev Jan 14 '14 at 04:34

1 Answers1

6

The only time I install multiple instances of services is for multiple environments, such as development, test, and production. Otherwise, it should be kept in the same service, assuming all of the code is logically relevant.

As for design pattern, I've been following a simple "pattern" for most services I create. I encourage answers as I myself don't know if this is a good pattern. It basically involves creating a master thread that is immediately started, and child threads based on what needs to be done. For your situation, the below could be a simple service layout for a user processor.

The Service class:

public partial class Service : ServiceBase
{
    private Processor _processor;

    public Service() { InitializeComponent(); }

    protected override void OnStart(string[] args)
    {
        _processor = new Processor();
        new System.Threading.Thread(_processor.Run).Start();
    }

    protected override void OnStop()
    {
        _processor.Stop();
    }
}

Processor:

public class Processor
{        
    private bool _continue;
    private List<UserProcessor> _userProcessors; // List of users being processed.

    public void Run()
    {
        _continue = true;
        while (_continue)
        {
            var users = getUsersToProcess();
            foreach (User user in users)
            {
                if (_userProcessors.Any(u => u.UserId == user.UserId) == false)
                {
                    // Start a new processor for the user since it wasn't found.
                    var processor = new UserProcessor(user);
                    new System.Threading.Thread(processor.Run).Start();
                    _userProcessors.Add(processor);
                }
            }

            System.Threading.Thread.Sleep(1000);
        }
    }

    public void Stop()
    {
        _continue = false;

        foreach (var processer in _userProcessors)
            processer.Stop();
    }

    private List<User> getUsersToProcess() { throw new NotImplementedException(); }
}

And of course, UserProcessor is nearly setup the same as Processor, but with different code inside of the while loop. This is where you would do your database interaction, but I'll let you figure this part out.

matth
  • 6,112
  • 4
  • 37
  • 43
  • @Dev, you may also checkout [Code Review](http://codereview.stackexchange.com/) in case you have a working example that you want critiqued. – matth Jan 17 '14 at 14:29
  • 1
    @making3, did you miss out the code to add the UserProcessor to the _userProcessors collection after calling its starting its Run task? – samneric Nov 14 '14 at 21:32
  • @samneric, you're correct, good catch. It would compile, but the Stop() wouldn't properly function at that point, since _userProcessors wouldn't be populated. – matth Nov 14 '14 at 22:43
  • also, I started using the code - nice thank you! - I just switched from Threading.Thread.Start to Task.Start for the contemporary aspect :) – samneric Nov 17 '14 at 15:12