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
Related
I am working on wpf application where so many UI screens are available and each UI contains lots of processing using multi threading, task await, dispatcher and, background worker. So now I have two buttons START and STOP. Now when I will click START button then whole application's process(long running process) need to run in while loop. Which causing application freeze. So now I want to transfer my process in another class in another normal application. which will contains only logic and I will need to send only single parameter to that application.
Now I want to achieve like when I will click on start button from my WPF application then another application(which contains only cs file there will be not any type of UI) need to run in while loop. And again when I will click STOP button then again that application need to stop it's work. I don't know about it's logic how to implement but I have an idea like I describe. So please can you guide me little bit that how can I implement that ?
For that like I have a WPF application and second one is console application.
Now in my Console Application code is like :
public static void Main(string[] args)
{
startProcess("This is running");
}
public static void startProcess(string name)
{
StreamWriter log;
string filePath = #"D:\TimeLogFile.txt";
for (int i = 0; i <= 10; i++)
{
log = File.AppendText(filePath);
log.WriteLine(name);
log.Close();
}
}
now I need to pass string parameter from my WPF application and want to run this console application from my WPF application. So please can you guide me that how can I achive it ?
from WPF application when I will click Start button then I want to run console application with passing parameters. I have try below code which is running my console application but don't know how to pass parameter and fetch it on console application side.
using(System.Diagnostics.Process process = new System.Diagnostics.Process())
{
process.StartInfo.UseShellExecute = false;
process.StartInfo.FileName = #"D:\StockTest.exe";
process.StartInfo.CreateNoWindow = true;
process.Start();
}
it's running console application but I want to pass parameter also there. So how can I pass parameter to console application and run console application.
I can suggest you the abstract design of the class .
When you click on the start button , in the command handler from the view model or code behind you can fire the task and out your long running code inside the class .
For example:
Your command handler. Where LongRunningLogic is the class where your long running code should go .
LongRunningLogic _longRunningLogic = new LongRunningLogic();
Task LongRunningTask = Task.Factory.StartNew(() =>
{
_longRunningLogic.LongRunningTask(cts);
});
Actual method which performs long running operation :
class LongRunningLogic
{
public void LongRunningTask(CancellationTokenSource cts)
{
while (!cts.IsCancellationRequested )
{
//Long running code
}
}
}
To stop this operation on "Stop" click, you can do through CancellationTokenSource. Define a CancellationTokenSource at the class level of the view model and when user clicks on Stop, raise the CancellationTokenSource.
Ex:
CancellationTokenSource cts = new CancellationTokenSource();
On your stop command handler , raise cancellationtokensource like this .
cts.Cancel();
You may capitalize on the following idea:
public class Runner
{
private readonly MyClass _object;
private int _flag;
public Runner(Object param)
{
_object = new MyClass(param);
}
public void Start()
{
if (Interlocked.CompareExchange(ref _flag, 1, 0) == 0)
{
Task.Factory.StartNew(job);
}
}
private void job()
{
while (Interlocked.CompareExchange(ref _flag, 1, 1) == 1)
{
// do the job on _object
}
}
public void Stop()
{
Interlocked.Exchange(ref _flag, 0);
}
}
You then create a Runner instance in GUI, and call Start in your START button handler, and Stop - inside STOP handler. MyClass and param should be modified accordinally as well.
Your while loop is inside the job function, put your logic there. Then you hit STOP, it would stop on the next loop iteration, so it may take some time. Later you may implement some cancellation logic to react faster.
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);
}
}
Sorry if this is an stupid question, but I'm pretty new to Windows Services and want to make sure I understand the proper way to approach this situation.
I have a Windows Service that is meant to watch for files and if those files exist, it processes them. I was looking through an old developer's code and they used Thread.Sleep() if files didn't exist. I understand that this is bad practice and have seen it first-hand that this locks up the service.
Here's a simplified example of my logic:
private Task _processFilesTask;
private CancellationTokenSource _cancellationTokenSource;
public Start()
{
_cancellationTokenSource = new CancellationTokenSource();
_processFilesTask = Task.Run(() => DoWorkAsync(_cancellationTokenSource.Token))
}
public async Task DoWorkAsync(CancellationToken token)
{
while(!token.IsCancellationRequested)
{
ProcessFiles();
//await Task.Delay(10000);
}
}
public Stop()
{
_cancellationTokenSource.Cancel();
_processFilesTask.Wait();
}
private void ProcessFiles()
{
FileInfo xmlFile = new DirectoryInfo(Configs.Xml_Input_Path).GetFiles("*.xml").OrderBy(p => p.CreationTime).FirstOrDefault();
if(xmlFile != null)
{
//read xml
//write contents to db
//move document specified in xml to another file location
//delete xml
}
}
My first question: Is any sort of Delay or Pause even needed? If I don't have any pause then this service will constantly look for files on a remote server. Is this something I have to worry about or is it a pretty light-weight process?
Second question: If it would be better to pause instead of constantly hitting this server, is this a better approach or what would you recommend?
public async Task DoWorkAsync(CancellationToken token)
{
while(!token.IsCancellationRequested)
{
ProcessFiles();
await Task.Delay(TimeSpan.FromMilliseconds(10000), token).ContinueWith(_processFilesTask=> { });
}
}
Thanks for your help!
You can use timer to check desired files and folder. Here is outline.
Add Timer in your service class (one that inherits ServiceBase class)
private System.Timers.Timer myTimer;
Initialize timer in OnStart method.
protected override void OnStart(string[] args)
{
// Set the Interval to 1 seconds (1000 milliseconds).
myTimer = new System.Timers.Timer(1000);
// Hook up the Elapsed event for the timer.
myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
myTimer.Enabled = true;
}
Define elapsed event handler.
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
//Write your file handling logic here.
//Service will execute this code after every one second interval
//as set in OnStart method.
}
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();
}
}
I want to call a Business layer method from a Windows service (done using C# and .NET) after every 10 seconds. However, i dont want to use the Timer_Elapsed event since it starts up another thread/process if the first thread/process is still running. I just need a single threaded approach, since multiple calls to the same Business method creates unwanted complications.
So i added a do--while loop in the on_start. I know this is not the correct way since it spawns this process which becomes an orphan if the service is shut down.
How can i approach this problem ?
Regards,
Chak
There's another way to get timed execution, the WaitHandle.WaitOne() method provides a timeout argument. That works very nicely in a service as it lets you implement the need to stop the service and periodic execution in a single method call. The template looks like this:
Thread Worker;
AutoResetEvent StopRequest = new AutoResetEvent(false);
protected override void OnStart(string[] args) {
// Start the worker thread
Worker = new Thread(DoWork);
Worker.Start();
}
protected override void OnStop() {
// Signal worker to stop and wait until it does
StopRequest.Set();
Worker.Join();
}
private void DoWork(object arg) {
// Worker thread loop
for (;;) {
// Run this code once every 10 seconds or stop right away if the service
// is stopped
if (StopRequest.WaitOne(10000)) return;
// Do work...
//...
}
}
Use a timer, but as soon as you enter the Timer handler method, disable the timer so that no more events are raised. Just before exiting the handler, re-enable the timer.
Check out this discussion, and in particular the answer by jsw. It suggests a synchronization mechanism to prevent multiple simultaneous calls to the business logic. Just disabling the timer in the Elapsed handler method isn't guaranteed to prevent parallel calls since the handler is invoked on a separate thread. Use a lock as jsw suggests, and stop the timer within the synchronized code block.
Alternatively, you could use a Timer and set the AutoReset property to false. That way, the Elapsed event is raised only once and you can reset the timer manually towards the end of the handler method.
while(true)
{
..do something
Thread.sleep( some time or day);
}
Thread thread;
private void DoWork(object arg)
{
while (true)
{
// Run this code once every 20 seconds or stop if the service is stopped
try
{
Thread.Sleep(20000);
//Do work....
}
catch(ThreadInterruptedException)
{
return;
}
}
}
protected override void OnStart(string[] args)
{
// Start the thread
thread = new Thread(DoWork);
mWorker.Start();
}
protected override void OnStop()
{
// interrupt thread and wait until it does
thread.Interrupt();
thread.Join();
}