I’ve been reading a lot of tutorials/helpdesks (including this one) on windows services and threading to figure out the best way to accomplish the below goal. I can’t figure out a few things though, so now i’m wondering if I choose the right way to go or not and if I did, how do I implement it.
The goal:
I need to perform 5 seperate tasks on the background, so I want to create a windows service. Besides the service I want a form application to show information about the service. From what I’ve read I should use a socket server to handle communication.
My plan:
- Create a windows service
- Create a async socket server class and start it in the onstart method
- When the socket server is properly started and ready, call a method
on the main service startTasks. - Create a seperate class for each task with an executeTask method
- In the startTasks method I will start a thread for each task so they
can all run simultanious. - When a task has something to report it should call a method on the
main service called sendData(msg) - The senddata method should call a method in the socket server class
that sends the msg to all connected clients.
The problem is with 3, 6 and 7 and involve the “Call method on other thread/class”.
- How can I let the asycn server call the startTasks method when its
ready - How can i sendData via this server from a seperate thread.
Simplefied service:
public partial class SecurityCheck : ServiceBase
{
private ComServer _comServer;
private CheckRequest _checkRequest;
private readonly Thread[] _threads = new Thread[1];
private int _tNr;
public SecurityCheck()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
_comServer = new ComServer();
}
protected override void OnStop()
{
_comServer.CloseSockets();
if (_checkRequest != null)
_checkRequest.ServiceStarted = false;
foreach (Thread t in _threads)
{
if (t != null)
t.Join(new TimeSpan(0, 2, 0));
}
}
internal void StartTasks()
{
_checkRequest = new CheckRequest { ServiceStarted = true };
var st = new ThreadStart(_checkRequest.ExecuteTask);
_threads[_tNr] = new Thread(st);
_threads[_tNr].Start();
_tNr++;
}
internal void SendData(string msg)
{
_comServer.SendData(msg);
}
}
Simplefied task
public class CheckRequest
{
public bool ServiceStarted;
public CheckRequest()
{
//construct me
}
public void ExecuteTask()
{
while (ServiceStarted)
{
try
{
//perform task
//what to do to send data?
}
catch (Exception ex)
{
}
// yield
if (ServiceStarted)
{
Thread.Sleep(new TimeSpan(0, 0, 10));
}
}
Thread.CurrentThread.Abort();
}
}
For the communications between the Service and the Clients I would definitely go with (duplex) WCF instead of sockets. This will save you a lot of tedious and errorprone coding.
Secondly, having a seperate class for each task with a executeTask method sounds like you hail from the Java world or runnable objects. In C#, you can just code the tasks as seperate methods and start them as a task be executed asynchronously. When they have something to report to the clients they can just send it to the clients themselves through a duplex channel between the Clients and the server.
Using WCF and TPL for this project should pretty much solve all the issues you describe and have you home in time for dinner. It may cost a little time now to get aqcuainted with these newer technologies but it will save you heaps of time lateron by having shorter code that is easier to transfer and has less room for bugs.
Regards Gert-Jan