Start a process after a certain time interval in C#? - c#

I have a c# wpf application where in the main() method, I check for a certain condition and if it is true, I run a different process, however, I need to start the process after a certain timeout. So, for eg:
override OnStartUp()
{
if(condition == true)
{
ProcessStartInfo p = new ProcessStartInfo("filePath");
p.Start(); // This should wait for like say 5 seconds and then start.
return; // This will exit the current program.
}
}
I could use Thread.Sleep() but that will cause the current program to sleep as well.
So, in other words, I want the current program to terminate immediately and then new process to start after 5 seconds.
Thanks!
Is this possible?

What if the first process creates a third program. The first program exits immediately, whilst the third one will simply sleep for 5 seconds and then will start your second program.

You've got a few options:
Modify the process being launched and put the delay there. You can even wait for "the parent has ended" instead of a fixed time.
Windows built-in Scheduled Tasks
A batch file that uses the sleep command and then runs the program

You can use Task Scheduler api and setup one time task that will start app after next 5 seconds.Nice managed wrraper: taskscheduler.codeplex.com

You need to create a new Thread. In this thread you can use Thread.Sleep without blocking your program.
public class MyThread
{
public static void DoIt()
{
Thread.Sleep(100);
// DO what you need here
}
}
override OnStartUp()
{
if(condition == true)
{
ThreadStart myThread = new MyThread(wt.DoIt);
Thread myThread = new Thread(myThread);
myThread.Start();
}
}

I can recomend the very powerful
http://quartznet.sourceforge.net/
For all your scheduling needs.

Related

How to keep a task running after the main thread ends?

I have an application that runs every 15 minutes. I need to add a new task (Maybe a Method) which will be called by the application and should run asynchronously, so the application can complete within the 15 Minutes. If the new task takes longer than the application is running, it will be aborted and can't complete its work. How can I keep a Task running?
There's a few ways you can go about this.
Independent process
The first is, don't run a task, run an independent process that can do the work. The first process will end when it needs to; the worker process will end when it needs to, and there's no communication between them (unless there needs to be for a different reason).
// in main thread...
var process = new Process(); // create the process
...
process.Start();
// process.WaitForExit(); this is commented out because you want main process to end without waiting
// main then ends here
Now the above means creating two separate executables; one for the launcher and one for the worker. That means two separate projects... or not.
What you can do is have both sets of functionality in the same executable, and invoke the functionality you need by separating it with command-line arguments. In your main you could do:
static void Main(string[] args)
{
if (args.Length == 1 && args[0] == "worker")
DoWorkerStuff();
else
{
var process = new Process(); // create the process
...
// use process API to call yourself with the arg
process.Start();
// process.WaitForExit(); this is commented out because you want main process to end without waiting
}
// main then ends here for both the launcher and the worker
}
I like this approach because you have full isolation due to process boundaries, and yet you don't have to compile and maintain separate projects.
Wait on the main thread
The second way is for the main thread to wait until the worker task is done. Trying to have tasks outlive the main thread can be problematic. Waiting is easy
// in main thread...
var task = ... // however you create the task
...
task.Wait(); // or one of the other Wait() overloads
There are, of course, other ways to start background work (e.g. using Thread) and for ways for the background work to signal the main thread, but these all require that original thread to wait until the work is done.

Stop execution of any method without closing the application

I have an application which runs on a single thread, but does a lot of things (executing methods in a loop to automate webbrowser app).
I am a beginner, so the code is probably poorly organized, but I need to add a following feature to the program - a STOP button.
What it needs to do is simply send a 'return;' to any method that is or would be executed next, so that the program returns to a ready-and-waiting stage (i.e. I don't loose user provided data, but no other iteration of any loop is carried out etc.).
Any idea?
I tried System.Threading.Thread.CurrentThread.Abort(); but this actually kills the whole application. Any idea for a good generic solution?
Cheers!
Well first of all if you are just using one thread with your application. Then you cant send cancelTokens to your methods. However if you start using Tasks, which are threads then you can provide yourself the ability to use cancelTokens on your methods.
Here is a very simple example I wrote of using a cancelToken in a program that has threads.
class Program
{
static void Main(string[] args)
{
bool cancelToken = false;
Thread t = new Thread(new ThreadStart(() =>
{
while (!cancelToken)
{
Console.WriteLine("Running....");
Thread.Sleep(1000);
}
}));
t.Start();
Console.ReadKey();
cancelToken = true;
t.Join();
}
}
If you have a single-threaded GUI program, then you can't take any user commands while it's processing something. If you do as others have suggested, and dump the processing into a worker thread, then you can send an interrupt signal to that thread to stop it.

CPU friendly infinite loop

Writing an infinite loop is simple:
while(true){
//add whatever break condition here
}
But this will trash the CPU performance. This execution thread will take as much as possible from CPU's power.
What is the best way to lower the impact on CPU?
Adding some Thread.Sleep(n) should do the trick, but setting a high timeout value for Sleep() method may indicate an unresponsive application to the operating system.
Let's say I need to perform a task each minute or so in a console app.
I need to keep Main() running in an "infinite loop" while a timer will fire the event that will do the job. I would like to keep Main() with the lowest impact on CPU.
What methods do you suggest. Sleep() can be ok, but as I already mentioned, this might indicate an unresponsive thread to the operating system.
LATER EDIT:
I want to explain better what I am looking for:
I need a console app not Windows service. Console apps can simulate the Windows services on Windows Mobile 6.x systems with Compact Framework.
I need a way to keep the app alive as long as the Windows Mobile device is running.
We all know that the console app runs as long as its static Main() function runs, so I need a way to prevent Main() function exit.
In special situations (like: updating the app), I need to request the app to stop, so I need to infinitely loop and test for some exit condition. For example, this is why Console.ReadLine() is no use for me. There is no exit condition check.
Regarding the above, I still want Main() function as resource friendly as possible. Let asside the fingerprint of the function that checks for the exit condition.
To avoid the infinity loop simply use a WaitHandle. To let the process be exited from the outer world use a EventWaitHandle with a unique string. Below is an example.
If you start it the first time, it simple prints out a message every 10 seconds. If you start in the mean time a second instance of the program it will inform the other process to gracefully exit and exits itself also immediately. The CPU usage for this approach: 0%
private static void Main(string[] args)
{
// Create a IPC wait handle with a unique identifier.
bool createdNew;
var waitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, "CF2D4313-33DE-489D-9721-6AFF69841DEA", out createdNew);
var signaled = false;
// If the handle was already there, inform the other process to exit itself.
// Afterwards we'll also die.
if (!createdNew)
{
Log("Inform other process to stop.");
waitHandle.Set();
Log("Informer exited.");
return;
}
// Start a another thread that does something every 10 seconds.
var timer = new Timer(OnTimerElapsed, null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
// Wait if someone tells us to die or do every five seconds something else.
do
{
signaled = waitHandle.WaitOne(TimeSpan.FromSeconds(5));
// ToDo: Something else if desired.
} while (!signaled);
// The above loop with an interceptor could also be replaced by an endless waiter
//waitHandle.WaitOne();
Log("Got signal to kill myself.");
}
private static void Log(string message)
{
Console.WriteLine(DateTime.Now + ": " + message);
}
private static void OnTimerElapsed(object state)
{
Log("Timer elapsed.");
}
You can use System.Threading.Timer Class which provides ability to execute callback asynchronously in a given period of time.
public Timer(
TimerCallback callback,
Object state,
int dueTime,
int period
)
As alternative there is System.Timers.Timer class which exposes Elapsed Event which raises when a given period of time is elapsed.
Why would you condone the use of an infinite loop? For this example would setting the program up as a scheduled task, to be run every minute, not be more economical?
Why don't you write a small application and use the system's task scheduler to run it every minute, hour...etc?
Another option would be to write a Windows Service which runs in the background. The service could use a simple Alarm class like the following on MSDN:
http://msdn.microsoft.com/en-us/library/wkzf914z%28v=VS.90%29.aspx#Y2400
You can use it to periodically trigger your method. Internally this Alarm class uses a timer:
http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
Just set the timer's interval correctly (e.g. 60000 milliseconds) and it will raise the Elapsed event periodically. Attach an event handler to the Elapsed event to perform your task. No need to implement an "infinite loop" just to keep the application alive. This is handled for you by the service.
I did this for an application that had to process files as they were dropped on a folder. Your best bet is a timer (as suggested) with a Console.ReadLine() at the end of "main" without putting in a loop.
Now, your concern about telling the app to stop:
I have also done this via some rudimentary "file" monitor. Simply creating the file "quit.txt" in the root folder of the application (by either my program or another application that might request it to stop) will make the application quit. Semi-code:
<do your timer thing here>
watcher = new FileSystemWatcher();
watcher.Path = <path of your application or other known accessible path>;
watcher.Changed += new FileSystemEventHandler(OnNewFile);
Console.ReadLine();
The OnNewFile could be something like this:
private static void OnNewFile(object source, FileSystemEventArgs e)
{
if(System.IO.Path.GetFileName(e.FullPath)).ToLower()=="quit.txt")
... remove current quit.txt
Environment.Exit(1);
}
Now you mentioned that this is (or could be) for a mobile application? You might not have the file system watcher. In that case, maybe you just need to "kill" the process (you said "In special situations (like: updating the app), I need to request the app to stop". Whoever the "requester" to stop it is, should simply kill the process)
It sounds to me like you want Main() to enter an interruptable loop. For this to happen, multiple threads must be involved somewhere (or your loop must poll periodically; I am not discussing that solution here though). Either another thread in the same application, or a thread in another process, must be able to signal to your Main() loop that it should terminate.
If this is true, then I think you want to use a ManualResetEvent or an EventWaitHandle . You can wait on that event until it is signalled (and the signalling would have to be done by another thread).
For example:
using System;
using System.Threading;
using System.Threading.Tasks;
namespace Demo
{
class Program
{
static void Main(string[] args)
{
startThreadThatSignalsTerminatorAfterSomeTime();
Console.WriteLine("Waiting for terminator to be signalled.");
waitForTerminatorToBeSignalled();
Console.WriteLine("Finished waiting.");
Console.ReadLine();
}
private static void waitForTerminatorToBeSignalled()
{
_terminator.WaitOne(); // Waits forever, but you can specify a timeout if needed.
}
private static void startThreadThatSignalsTerminatorAfterSomeTime()
{
// Instead of this thread signalling the event, a thread in a completely
// different process could do so.
Task.Factory.StartNew(() =>
{
Thread.Sleep(5000);
_terminator.Set();
});
}
// I'm using an EventWaitHandle rather than a ManualResetEvent because that can be named and therefore
// used by threads in a different process. For intra-process use you can use a ManualResetEvent, which
// uses slightly fewer resources and so may be a better choice.
static readonly EventWaitHandle _terminator = new EventWaitHandle(false, EventResetMode.ManualReset, "MyEventName");
}
}
You can use Begin-/End-Invoke to yield to other threads. E.g.
public static void ExecuteAsyncLoop(Func<bool> loopBody)
{
loopBody.BeginInvoke(ExecuteAsyncLoop, loopBody);
}
private static void ExecuteAsyncLoop(IAsyncResult result)
{
var func = ((Func<bool>)result.AsyncState);
try
{
if (!func.EndInvoke(result))
return;
}
catch
{
// Do something with exception.
return;
}
func.BeginInvoke(ExecuteAsyncLoop, func);
}
You would use it as such:
ExecuteAsyncLoop(() =>
{
// Do something.
return true; // Loop indefinitely.
});
This used 60% of one core on my machine (completely empty loop). Alternatively, you can use this (Source) code in the body of your loop:
private static readonly bool IsSingleCpuMachine = (Environment.ProcessorCount == 1);
[DllImport("kernel32", ExactSpelling = true)]
private static extern void SwitchToThread();
private static void StallThread()
{
// On a single-CPU system, spinning does no good
if (IsSingleCpuMachine) SwitchToThread();
// Multi-CPU system might be hyper-threaded, let other thread run
else Thread.SpinWait(1);
}
while (true)
{
// Do something.
StallThread();
}
That used 20% of one core on my machine.
To expound on a comment CodeInChaos made:
You can set a given thread's priority. Threads are scheduled for execution based on their priority. The scheduling algorithm used to determine the order of thread execution varies with each operating system. All threads default to "normal" priority, but if you set your loop to low; it shouldn't steal time from threads set to normal.
The Timer approach is probably your best bet, but since you mention Thread.Sleep there is an interesting Thread.SpinWait or SpinWait struct alternative for similar problems that can sometimes be better than short Thread.Sleep invocations.
Also see this question: What's the purpose of Thread.SpinWait method?
Lots of "advanced" answers here but IMO simply using a Thread.Sleep(lowvalue) should suffice for most.
Timers are also a solution, but the code behind a timer is also an infinity loop - I would assume - that fires your code on elapsed intervals, but they have the correct infinity-loop setup.
If you need a large sleep, you can cut it into smaller sleeps.
So something like this is a simple and easy 0% CPU solution for a non-UI app.
static void Main(string[] args)
{
bool wait = true;
int sleepLen = 1 * 60 * 1000; // 1 minute
while (wait)
{
//... your code
var sleepCount = sleepLen / 100;
for (int i = 0; i < sleepCount; i++)
{
Thread.Sleep(100);
}
}
}
Regarding how the OS detects if the app is unresponsive. I do not know of any other tests than on UI applications, where there are methods to check if the UI thread processes UI code. Thread sleeps on the UI will easily be discovered. The Windows "Application is unresponsive" uses a simple native method "SendMessageTimeout" to see detect if the app has an unresponse UI.
Any infinity loop on an UI app should always be run in a separate thread.
To keep console applications running just add a Console.ReadLine() to the end of your code in Main().
If the user shouldn't be able to terminate the application you can do this with a loop like the following:
while (true){
Console.ReadLine();
}

Timed windows service crashing due to multiple threads running

I'm working on a simple web service which exports data from some data store into the database.
The service runs every 20 seconds (testing interval).
Intervals are implemented through System.Timers.Timer class.
What is happening at the moment is:
Service starts
Timer starts
20 seconds pass and service starts the export
Export doesn't finish within next 20 seconds and another thread kicks off attempting to do the same export.
Eventually service crashes.
I was going to wrap the export into a separate thread, but not sure whether this will fully fix the problem.
Increasing a time interval isn't an option because I'm not sure how big the future exports will be.
Any suggestions are welcome.
Thank you
Edit:
I guess what I'm after is:
1. Start timer
2. Start thread
3. Start export
4. Don't let timer to start another thread until previous one completes...
How about in Step 3, you first disable the timer, then when you are done with the export, you re-enable the timer?
I would do something like this.
public class MyServiceController
{
private Thread m_Thread = new Thread(() => { Run(); });
private ManualResetEvent m_StopSignal = new ManualResetEvent();
public void Start()
{
m_Thread.Start();
}
public void Stop()
{
m_StopSignal.Set(); // Give it chance to end on its own.
if (!m_Thread.Join(TimeSpan.FromSeconds(30))
{
// Tear everything down forcefully as an absolute last resort.
m_Thread.Abort();
}
}
private void Run()
{
while (!m_StopSignal(TimeSpan.FromSeconds(20))
{
// Put your code here.
}
}
}
This approach allocates a single dedicated thread for processing which keeps everything synchronous. Notice that it uses a WaitHandle to throttle the intervals. It is also important to note that I have left out a lot of code that would make MyServiceController more robust like dealing with callers who want to call Start multiple times, making sure the worker thread ends if it does not want to stop peacefully, etc.
Sometimes you don't want to stop your timer because it might spawning multiple threads. In this case you wrap the critical parts of each thread in Monitor.TryEnter block, locking on a shared object, so that if a thread is still running when the timer fires again, the new thread falls through harmlessly.
private static object lockObject = new object();
public void DoSomething()
{
if (System.Threading.Monitor.TryEnter(lockObject))
{
try
{
// critical stuff
}
finally
{
System.Threading.Monitor.Exit(lockObject);
}
}
}

Pausing a method for set # of milliseconds

I need to do a sort of "timeout" or pause in my method for 10 seconds (10000 milliseconds), but I'm not sure if the following would work as i do not have multi-threading.
Thread.Sleep(10000);
I will try to use that current code, but I would appreciate if someone could explain the best and correct way of doing this, especially if the above code does not work properly. Thanks!
UPDATE: This program is actually a console application that in the function in question is doing many HTTPWebRequests to one server, so I wish to delay them for a specified amount of milliseconds. Thus, no callback is required - all that is needed is an "unconditional pause" - basically just the whole thing stops for 10 seconds and then keeps going. I'm pleased that C# still considers this as a thread, so Thread.Sleep(...) would work. Thanks everybody!
You may not have multi-threading, but you're still executing within a thread: all code executes in a thread.
Calling Thread.Sleep will indeed pause the current thread. Do you really want it to unconditionally pause for 10 seconds, or do you want to be able to be "woken up" by something else happening? If you're only actually using one thread, calling Sleep may well be the best way forward, but it will depend on the situation.
In particular, if you're writing a GUI app you don't want to use Thread.Sleep from the UI thread, as otherwise your whole app will become unresponsive for 10 seconds.
If you could give more information about your application, that would help us to advise you better.
Thread.Sleep is fine, and AFAIK the proper way. Even if you are not Multithreaded: There is always at least one Thread, and if you send that to sleep, it sleeps.
Another (bad) way is a spinlock, something like:
// Do never ever use this
private void DoNothing(){ }
private void KillCPU()
{
DateTime target = DateTime.Now.AddSeconds(10);
while(DateTime.Now < target) DoNothing();
DoStuffAfterWaiting10Seconds();
}
This is sadly still being used by people and while it will halt your program for 10 seconds, it will run at 100% CPU Utilization (Well, on Multi-Core systems it's one core).
That will indeed pause the executing thread/method for 10 seconds. Are you seeing a specific problem?
Note that you shouldn't Sleep the UI thread - it would be better to do a callback instead.
Note also that there are other ways of blocking a thread that allow simpler access to get it going again (if you find it is OK after 2s); such as Monitor.Wait(obj, 10000) (allowing another thread to Pulse if needed to wake it up):
static void Main() {
object lockObj = new object();
lock (lockObj) {
new Thread(GetInput).Start(lockObj);
Monitor.Wait(lockObj, 10000);
}
Console.WriteLine("Main exiting");
}
static void GetInput(object state) {
Console.WriteLine("press return...");
string s = Console.ReadLine();
lock (state) {
Monitor.Pulse(state);
}
Console.WriteLine("GetInput exiting");
}
You can do this with Thread.Interrupt too, but IMO that is messier.
You could use a separate thread to do it:
ThreadPool.QueueUserWorkItem(
delegate(object state)
{
Thread.Sleep(1000);
Console.WriteLine("done");
});
But, if this is a Windows Forms app, you will need to invoke the code after the delay from the Gui thread (this article, for example: How to update the GUI from another thread in C#?).
[Edit] Just saw your update. If it's a console app, then this will work. But if you haven't used multiple threads so far, then you need to be aware that this code will be executed in a different thread, which means you will have to take care about thread synchronization issues.
If you don't need background workers, stick to "keeping it simple".
Here is a pause class that will pause for the desired milliseconds and wont consume your CPU resources.
public class PauseClass
{
//(C) Michael Roberg
//Please feel free to distribute this class but include my credentials.
System.Timers.Timer pauseTimer = null;
public void BreakPause()
{
if (pauseTimer != null)
{
pauseTimer.Stop();
pauseTimer.Enabled = false;
}
}
public bool Pause(int miliseconds)
{
ThreadPriority CurrentPriority = Thread.CurrentThread.Priority;
if (miliseconds > 0)
{
Thread.CurrentThread.Priority = ThreadPriority.Lowest;
pauseTimer = new System.Timers.Timer();
pauseTimer.Elapsed += new ElapsedEventHandler(pauseTimer_Elapsed);
pauseTimer.Interval = miliseconds;
pauseTimer.Enabled = true;
while (pauseTimer.Enabled)
{
Thread.Sleep(10);
Application.DoEvents();
//pausThread.Sleep(1);
}
pauseTimer.Elapsed -= new ElapsedEventHandler(pauseTimer_Elapsed);
}
Thread.CurrentThread.Priority = CurrentPriority;
return true;
}
private void pauseTimer_Elapsed(object sender, ElapsedEventArgs e)
{
pauseTimer.Enabled = false;
}
}
Yes, that works just fine.
You don't have to have multiple threads to make use of some of the methods in the Thread class. You always have at least one thread.
For a timeout, you should have a static volatile boolean isRunning class field. When the new thread starts, the isRunning must become true, and at the end must become false.
The main thread should have a method that loops for the isRunning during the timeout you define. When the timeout ends, you should implement the logic. But, never use the abort thread method.
A pause... there isn't a straightforward solution. It depends on what you are doing inside the thread. However, you could look at Monitor.Wait.
If you can have an async method, you can do something like to pause the function at a certain location. Once pause is set false it will continue executing the rest of the code in the method. Since this is an async method and delay is async too UI execution wouldn't be affected.
* Please note that asyn is supported only in .net 4.5 and higher.
bool pause = true;
void async foo()
{
//some code
while (pause)
{
await Task.Delay(100);
}
//some code
}

Categories

Resources