Aamir
Aamir

Reputation: 1757

Expert opinion needed on developing a C# Windows Service which will use/create many threads

I am developing c# windows service that will be watching several files, folders and DB tables for any changes. There are three types of watchers (I call them watchers).

  1. FileWatcher : Constantly watcher for a file using .Net FileSystemWatcher and raises an event where alert is to be sent. After alert is sent, watch functionality resumes.

  2. FolderWatcher : Constantly watcher for a folder using .Net Timer and raises an event where alert is to be sent upon certain conditions. After alert is sent, watch functionality resumes.

  3. DBWatcher: Executes an SQL query after each minute (Timer) and sends an alert if the result is wrong.

You can guess that these all watchers will run all the time where windows service is running.

They all implement an interface IWatcher and provide a method BeginWatch that performs the operations needed for each watcher, such as querying the DB every minute using timer (if watcher is DBWatcher). The input for creating these watchers is an XML file. It contains something like following:

<?xml version="1.0" encoding="utf-8"?>
<watchlist>

    <watcher type="FolderWatcher">
        <path>D:\Projects\.Net\V1\</path>
        <PauseInMinBtwAlerts>1</PauseInMinBtwAlerts>
        <alert>[email protected]</alert>
    </watcher>

    <watcher type="FileWatcher">
        <path>D:\Projects\.Net\</path>
        <fileName>e.txt</fileName>
        <alert>[email protected]</alert>
    </watcher>

    <watcher type="DBWatcher">
        <sqlquery>select blah blah blah ... </sqlquery>
        <connectionstring>connection string for the DB</connectionstring>
        <alert>[email protected]</alert>
    </watcher>

</watchlist>

This XML tells us how many watchers are to be created. There can be a dozens of watchers created.

Due to some issues we faced, we have decided that each watcher will be run on a different Thread. So in case of an unhandled exeption, only that thread can be stopped/killed and we inform the IT department through an email alert about the situation. We must be able to resume it later.

Now i m confused. as there are Threads, Async tasks, pooled threads, background threads etc etc. what should I use???/ I m new to this threading.

Let me tell you my requirement and then you may guide me to some proper solutions:

  1. I want each watcher to run in a separate thread.
  2. Thread MUST run continuously and my watcher must be able to watch until the windows service itself shuts down.
  3. Thread must be able to communicate with its parent thread (the class where each thread is created) to update it about its status.
  4. Any unhandled exception in a thread must be caught in the thread itself and then communicated to the parent class (using 3rd point).

I have created the following class that will be responsible for creating, communicating with, and managing all threads:

public class WatcherThreadsManager
{
    //This will keep list of all active threads ... as I will be communicating with them later
    private List<Thread> _watcherThreads;

    public WatcherThreadsManager()
    {
        this._watcherThreads = new List<Thread>();
    }

    //I will call this method and pass in any watcher which i want to run in a new thread
    public void CreateWatcherThread(IWatcher watcher)
    {
        Thread _watcher = new Thread(_createWatcherThread);

        //the Copy() will produce its deeply copied copy ... i wanted to make sure thread works on a free object .. not sure
        _watcher.Start(watcher.Copy());

        //Add Thread to threads' list
        this._watcherThreads.Add(_watcher);
    }

    private void _createWatcherThread(object wat)
    {
        IWatcher watcher = wat as IWatcher;
        try
        {
            //the following function will begin the watch.
            //I dont want any loop either .. as i want to call the BeginWatch() method only once.
            watcher.BeginWatch();
        }
        catch (Exception ex)
        {
            // i should be able to inform the parent thread about the exception so this thread is set to sleep. as we can reactivate it later when the issue fixes.
            // how to do that?
        }
    }
} 

What would be the best way to achieve what I want?

Upvotes: 4

Views: 6132

Answers (2)

svick
svick

Reputation: 244848

Due to some issues we faced, we have decided that each watcher will be run on a different Thread. So in case of an unhandled exeption, only that thread can be stopped/killed

This sounds like you don't need threads, you need to catch your exceptions. Why don't you do that?

Upvotes: 1

Alex S
Alex S

Reputation: 1221

You can achieve all of your requirements by using Tasks, here are few links for further reading:

  1. Creating threads - Task.Factory.StartNew vs new Thread()

  2. Best Practice LongRunning Task creation

  3. Task Report Progress

  4. Handling Task exceptions

Good luck!

Upvotes: 4

Related Questions