windows service application installation - c#

I am beginner to .NET.
I have a question regarding windows service application running multi-thread. My question is when I tried to register my application into windows service, I see my service status in "starting" in the service windows. I have included few lines code to show what I am trying to do.
protected override void OnStart(string [] args) {
timer = Timer(5000);
timer.Elapsed += new ElapsedEventHandler(OnElapsedTime);
timer.Start();
// when I commented out Application.Run() it runs perfect.
Application.Run(); // run until all the threads finished working
//todo
}
private void OnElapsedTime(object s, ElapsedEventArgs e) {
SmartThreadPool smartThreadPool = new SmartThreadPool();
while( i < numOfRecords){
smartThreadPool.QueueWorkItem(DoWork);
//.....
}
}
If you need further information please let me know.

Application.Run() in the context you've used it just tells the service to run itself again in the same application context. As a part of your Windows Service, an application context already exists within the context of your ServiceBase. Since it's a service, it won't stop until it's given an instruction to stop through either a method that requires it, an unhandled exception or an external command.
If you're concerned about preventing the stop from occurring while threads are in the midst of executing, you'll need a global lock of some sort indicating processes are working. It might be as simple as elevating the scope of your SmartThreadPool:
private SmartThreadPool _pool = null;
private SmartThreadPool Pool
{
get
{
if (_pool == null)
_pool = new SmartThreadPool();
return _pool;
}
}
protected override void OnStop()
{
if (Pool != null)
{
// Forces all threads to finish and
// achieve an idle state before
// shutting down
Pool.WaitForIdle();
Pool.Shutdown();
}
}

Related

Start multiple instances of the window service

I have created a windows service that reads an IBM MQ messages and processes them. My Win Service is currently designed OnStart it triggers a timer interval which calls the function that calls the class which does all the work (See code below).
What I am trying to accomplish is to scale (if that is the right word) the application, if there are a lot of messages on the queue to process we would like to run multiple instances/threads of the service. Ideal situation would be to have some type of configuration in the app.config that indicates how many threads or worker processes to have running. Is threading the right approach? Is there a better or preferred way? Right now what we are doing is installing a new instance of the service with a different name and it is getting quiet tedious.
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("Service Started", EventLogEntryType.Information);
_myTimer.Interval = 500; // half a second
_myTimer.Elapsed += OnTimer;
_myTimer.AutoReset = false;
_myTimer.Enabled = true;
}
public void OnTimer(object sender, ElapsedEventArgs args)
{
//If you want the main program to go ahead and shut down after some period of time, regardless of whether it's obtained the lock, use Monitor.TryEnter. For example, this will wait 15 seconds.
//bool gotLock = Monitor.TryEnter(_timerLock, TimeSpan.FromSeconds(15));
if (!Monitor.TryEnter(_timerLock))
{
// something has the lock. Probably shutting down.
return;
}
try
{
MqSyncJob mqSyncJob = new MqSyncJob(eventLog1);
mqSyncJob.ProcessSyncJobQueue();
}
catch (Exception ex)
{
eventLog1.WriteEntry(ex.ToString(), EventLogEntryType.Error);
}
finally
{
_myTimer.Start(); // re-enables the timer
Monitor.Exit(_timerLock);
}
}

error occured in window service

This is my first window service that I am writing, I need some help in writing it, I am trying to use single thread so that one thread can start the service
and the other thread can take care of calling the functions that does the database work. I am also using a timer so that this service only runs once a day below is my code
The reason i am posting this question is whenever I tried to install this service, it is throwing an error saying "fatal error occure", it doen't give me any details.
public partial class Service1 : ServiceBase
{
private DateTime _lastRun = DateTime.Now;
Thread workerThread;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
ThreadStart st = new ThreadStart(WorkerFunction);
workerThread = new Thread(st);
serviceStarted = true;
workerThread.Start();
}
protected override void OnStop()
{
// flag to tell the worker process to stop
serviceStarted = false;
// give it a little time to finish any pending work
workerThread.Join(new TimeSpan(0, 2, 0));
timer1.Enabled = false;
}
private void WorkerFunction()
{
while (serviceStarted)
{
EventLog.WriteEntry("Service working",
System.Diagnostics.EventLogEntryType.Information);
// yield
if (serviceStarted)
{
Thread.Sleep(new TimeSpan(0, 20000, 0));
}
timer1.Enabled = true;
timer1.Start();
}
// time to end the thread
Thread.CurrentThread.Abort();
}
private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
if (_lastRun.Date < DateTime.Now.Date)
{
timer1.Stop();
// does the actual work that deals with the database
}
timer1.Start();
}
There's a few things to check:
Be sure that you have configured the EventLog source correctly (MSDN). My answer to Windows service Started and stopped automatically, exception handling issue could be useful here also.
It looks like you are using a Windows Forms Timer - these require a UI message pump, which you won't have in a service (MSDN). You should instead investigate using the Timer class in the System.Threading namespace (MSDN).
In particular, you may find the using a System.Threading.Timer will simplify your code a great deal as this object will manage a bit more of the plumbing for you.
I would also advise against calling Thread.Abort(): it can be harmful and unpredictable, and in your case it doesn't appear that you need to use it at all. See To CurrentThread.Abort or not to CurrentThread.Abort and
http://msdn.microsoft.com/en-us/library/5b50fdsz.aspx.

Using a semaphore instead of while loop. Is this good or bad?

I have a process that runs in it's own thread and can be started/stopped without blocking. This will eventually go into a Windows service, but I am setting this up in a console app for now until it is fully fleshed out.
After the call to Start(), I want the main program thread to block until Ctrl-C is pressed. I know that this will work:
public static void Main(string[] args)
{
bool keepGoing = true;
var service = new Service();
System.Console.TreatControlCAsInput = false;
System.Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
{
e.Cancel = true;
service.Stop();
keepGoing = false; // Break the while loop below
};
service.Start();
while( keepGoing )
{
Thread.Sleep(100); // 100 is arbitrary
}
}
However, I find the flag and arbitrary sleep value bothersome. I know that the CPU cost is practically 0 in the while loop, but I'd rather have a "hard" block that releases as soon as the Ctrl-C handler is done. I devised the below, using a semaphore to block until the anonymous Ctrl-C handler is done:
public static void Main(string[] args)
{
var service = new Service();
var s = new Semaphore(1, 1);
System.Console.TreatControlCAsInput = false;
System.Console.CancelKeyPress += delegate(object sender, ConsoleCancelEventArgs e)
{
e.Cancel = true;
service.Stop();
s.Release(); // This will allow the program to conclude below
};
service.Start();
s.WaitOne(); // This will not block
s.WaitOne(); // This will block w/o CPU usage until the sempahore is released
}
Is this a bad design? Is it overkill? Is it dangerous?
EDIT:
I also hook up AppDomain.CurrentDomain.UnhandledException as follows:
AppDomain.CurrentDomain.UnhandledException += delegate {
service.Stop();
s.Release();
};
EDIT the 2nd:
I should note that it is crucial that the Stop() method get called on exit. #Adam Ralph has a perfectly good pattern for a hybrid console/service, but didn't have this information when answering the Q.
We have a similar requirement in a few of our apps. They are Windows services, but for debugging we often want to run them as console apps. Moreover, we usually code new apps as Windows services fairly early on but often don't want to have to actually run them as a service until later, once we've proved the concept, etc.
This is the pattern we use:-
using (var service = new Service())
{
if (Environment.UserInterActive)
{
service.Start();
Thread.Sleep(Timeout.Infinite);
}
else
{
ServiceBase.Run(service);
}
}
Telling the thread to sleep infinitely might seem inefficient, but this is only for debugging scenarios and the redundant thread costs no CPU time, just some memory (about 1MB), which is mostly composed of the stack space allocated to the thread. The process can still be exited with Ctrl+C or by closing the command window.
-- EDIT --
If you find that service.Dispose() is not being called when Ctrl+C is pressed (i.e. a rude abort happens) and the call to Dispose() is crucial, then I guess you could explicitly do this like so:-
using (var service = new Service())
{
if (Environment.UserInterActive)
{
Console.CancelKeyPress += (sender, e) => service.Dispose();
service.Start();
Thread.Sleep(Timeout.Infinite);
}
else
{
ServiceBase.Run(service);
}
}
Note that Stop() should be encapsulated in Dispose().

Schedule a windows service to run every two hours

I have created the Window Service VS2010, Now i want to Schedule that service to run after every 2Hour. For this what is the code..
You could use the RegisterWaitForSingleObject method in the ThreadPool class.
Your service code should look something like this (stolen heavily from here and here) :
private ManualResetEvent resetEvent = new ManualResetEvent(false);
private RegisteredWaitHandle handle;
public void OnStart()
{
resetEvent.Reset();
handle = ThreadPool.RegisterWaitForSingleObject(resetEvent, callBack, null, 7200000, false);
}
public void OnStop()
{
reset.Set();
}
private void callBack(object state, bool timeout)
{
if (timeout)
{
//Do Stuff Here
}
else
{
handle.Unregister(null);
}
}
In the Debug or Release folder, you will have an .exe version of the file.
Use Task scheduler to run it whenever you want to.
On Windows XP and Server 2003 you can access this from the Start Menu and clicking on Settings and then Control Panel to Scheduled Tasks
The above will constantly utilize your resources. For intermittent usage PS Service can do the job:
http://technet.microsoft.com/en-us/sysinternals/bb897542.aspx

C# question on preventing GUI from becoming sluggish when using backgroundworker/thread

I am trying to build a small application that logins into a server and gathers data from it constantly. The problem that I am having is that my GUI is slow to respond even when using either background worker or a thread. When my application tries to login into the server, I see "(Not Responding)" appear in my login form, but it logins in few seconds later without Windows giving the "The program has stopped responding... terminate application" dialog. When I click the start button on my application I noticed by GUI becomes very sluggish and unresponsive. I was wondering how I could improve the response time of my program. Here is the code for the Login form using a background worker and the code for my thread that gathers data from the server. I apologize for the last section of the code not being format correctly, but SO is being non-cooperative.
private void btnLogin_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txtAccount.Text) || string.IsNullOrEmpty(txtPassword.Text))
{
MessageBox.Show("Must Enter Username and Password");
return;
}
btnLogin.Enabled = false;
account = txtAccount.Text;
password = txtPassword.Text;
accountType = cmbAccountType.SelectedItem.ToString();
loginBackgroundWorker.RunWorkerAsync();
}
private void loginBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
loginSuccess=tradingDesk.Login(account, password, accountType);
}
private void loginBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (loginSuccess)
{
this.DialogResult = DialogResult.OK;
}
btnLogin.Enabled = true;
}
private void btnStart_Click(object sender, EventArgs e)
{
Thread dataThread=new Thread(GetServerData);
dataThread.IsBackground=true;
try
{
dataThread.Start();
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}}
private void GetServerData()
{
try
{
while (true)
{
lock (myLock)
{
//Perform Server Task with large amounts of data
}
}
}
catch
{
//Handle exception code
}
}
Try using BackgroundWorker for your processing - easier than handling threads yourself unless you're in the business of handling threads in a pool and you like that stuff (or you've been doing it like that since v1.0 as I have - you're just used to it that way).
I also put all my UI interactions into a background thread and marshall the calls back through to the UI thread. This article should help you out on both: Tools for Updating Windows Forms UI from Background Threads
Another test is to swap out your call to tradingDesk.Login with a simple sleep to see if that changes anything. And how's your CPU? Happen to notice if the thread or process spikes in CPU usage? Even a multi-threaded app that eats up all your CPU will stutter - Flash comes to mind - slows down my entire system even other processes.
Try setting Thread.Priority to something lower than the GUI.
Also, your thread is on the same cpu/core as the app (same process) so if it uses 100% then even with a lowered priority you might notice a difference.
There is a library I can't recall off the top of my head for parallel processing across cpus/cores - try that if priority doesn't fix it
This seems strange to me...:
private void btnStart_Click(object sender, EventArgs e)
{
Thread dataThread = new Thread(GetServerData); // Won't this go out of scope?
dataThread.IsBackground = true;
try
{
dataThread.Start(); // Isn't this asynchronous (i.e. doesn't block)?
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Seems to me that either dataThread.Start() is a blocking call, thus causing your UI thread to stall, or it's a non-blocking call, in which case the local reference dataThread goes out of scope almost immediately (presumably before the thread has had time to finish it's work)?
This is a perfect example of why ThreadPool exists. Please note, when you pass the delegate to the method you want threaded to the ThreadPool, the main UI thread (the one that drives the message pump) is free and clear, waiting for the next UI event. Unless you are communicating frequently with the UI thread, there should be no reason that the UI thread is bogged down to the point of becoming unresponsive.
private void btnStart_Click(object sender, EventArgs e)
{
// spawn the GetServerData() method on the ThreadPool
ThreadPool.QueueUserWorkItem(new WaitCallback(GetServerData));
// after the above is called, you'll immediately get here because
// the UI thread is free from having to process GetServerData()
return;
}
Note: WaitCallback delegate requires a single parameter of an object. Also, note the comment on the "lock" statement below.
private void GetServerData(object o)
{
try
{
while (true)
{
// if ANYTHING in the UI thread requires this lock (recurring timer),
// you've just eliminated ANY benefit to having this on a separate thread
lock (myLock)
{
// processor intensive code
}
}
}
catch
{
// handle exceptions
}
}

Categories

Resources