Wireless endless loop

Writing an infinite loop is simple:

while(true){ //add whatever break condition here } 

But this will cause CPU performance to fail. This thread of execution will be as much as possible from the processor power.

What is the best way to reduce the impact on the processor? Adding some Thread.Sleep(n) should do the trick, but setting a high timeout value for the Sleep() method may indicate an unresponsive application to the operating system.

Let's say I need to complete a task every minute or so in a console application. I need Main() work in an "infinite loop" while the timer fires an event that will execute the task. I would like to keep Main() with the least impact on the CPU.

What methods do you suggest. Sleep() may be fine, but as I mentioned, this may indicate an unresponsive thread to the operating system.

LATER EDIT:

I want to better explain what I'm looking for:

  • I need a console application, not a Windows service. Console applications can simulate Windows services on Windows Mobile 6.x systems with the Compact Framework.

  • I need the application to be supported as long as the Windows Mobile device is running.

  • We all know that a console application runs as long as its static function Main () is started, so I need a way to prevent Main () from exiting.

  • In special situations (for example: updating the application) I need to ask the application to stop, so I need to contact endlessly and check some kind of exit condition. For example, therefore Console.ReadLine() does not suit me. There is no output status check.

  • As for the foregoing, I still want the Main () function to be as resource-friendly as possible. Let the fingerprint of the function that checks the exit condition be checked.

+44
c # infinite-loop console-application
Sep 13 '11 at 12:50
source share
11 answers

To avoid an infinity loop, just use WaitHandle . To allow a process to exit the outside world, use an EventWaitHandle with a unique string. The following is an example.

If you run it for the first time, it just prints a message every 10 seconds. If you run the average time of the second instance of the program, it will tell another process to gracefully exit and exit immediately. 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."); } 
+41
Sep 11 '12 at 10:40
source share
— -

You can use the System.Threading.Timer Class, which provides the ability to execute a callback asynchronously in a given period of time.

 public Timer( TimerCallback callback, Object state, int dueTime, int period ) 

As an alternative, there is a System.Timers.Timer class that provides an Elapsed Event that expands when a given period of time expires.

+9
Sep 13 '11 at 12:52
source share

Why do you indulge in using an infinite loop? In this example, should a program be installed as a scheduled task every minute, no more economically?

+1
Sep 13 '11 at 12:53 on
source share

Why don't you write a small application and use the system task scheduler to launch it every minute, hour ... etc.?

Another option is to write a Windows service that runs in the background. A service can use a simple Alarm class, such as the following on MSDN:

http://msdn.microsoft.com/en-us/library/wkzf914z%28v=VS.90%29.aspx#Y2400

You can use it to periodically run your method. Inside this Alarm class, a timer is used:

http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx

Just set the timer interval correctly (for example, 60,000 milliseconds), and it periodically raises the Expired event. Attach an event handler to the Elapsed event to complete your task. There is no need to implement an “endless loop” to keep the application pending. This is done for you by the service.

+1
Sep 13 '11 at 12:57
source share

It seems to me that you want Main () to enter an intermittent loop. For this to happen, you need to use several threads (or your cycle should be logged periodically, but I do not discuss this solution here). Any other thread in one application or thread in another process should be able to signal its Main () loop, which should end.

If this is true, I think you want to use ManualResetEvent or EventWaitHandle . You can wait for this event until it is signaled (and the signal must be executed 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"); } } 
+1
Sep 11
source share

You can use Begin-/End-Invoke to go to other threads. For example.

 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 code ( Source ) in the body of the 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(); } 

This used 20% of one core on my machine.

0
Sep 13 '11 at 13:14
source share

Outline the CodeInChaos comment text:

You can set the priority of the stream . Threads are scheduled to run based on their priority. The scheduling algorithm used to determine the execution order of threads depends on each operating system. All threads default to "normal" priority, but if you set your loop to low; he should not waste time from threads set to normal.

0
Sep 13 2018-11-11T00:
source share

I did this for an application that was supposed to process files as they were deleted in the folder. It is best to use a timer (as suggested) with Console.ReadLine () at the end of "main", without inserting a loop.

Now your concern is about stopping the application:

I also did this through some rudimentary “file” monitor. Simply creating the quit.txt file in the root folder of the application (either by my program or by another application that may require it to stop) will cause the application to shut down. 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(); 

OnNewFile might 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 have you mentioned that this (or maybe) is for a mobile application? You may not have a file system watcher. In this case, perhaps you just need to “kill” the process (you said: “In special situations (for example: updating the application) I need to ask the application to stop.” Whoever “requesting” to stop it should just kill the process)

0
May 18 '12 at 20:01
source share

The Timer approach is likely to be your best bet, but since you mention Thread.Sleep, there is an interesting Thread.SpinWait or SpinWait struct alternative for similar problems, which can sometimes be better than short Thread.Sleep invocations.

Also see this question: What is the purpose of the Thread.SpinWait method?

0
Sep 11 '12 at 9:40
source share

There are many “extended” answers here, but IMO just uses Thread.Sleep (lowvalue) for most.

Timers are also a solution, but the code behind the timer also represents an infinity loop - I would assume that it runs your code at expired intervals, but they have the correct infinity setting.

If you need a big dream, you can cut it into smaller sleeps.

So, something like a simple and lightweight 0% processor solution for a non-UI application.

 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 that the application is not responding. I don’t know of any other tests besides UI applications, where there are ways to check if the user interface processes UI code. A thread to sleep in the user interface will be easily detected. The Application Not Responding application uses its simple SendMessageTimeout native method to find out if the application has a user interface for responding to a request.

Any infinity loop in a UI application should always run in a separate thread.

0
May 20 '16 at 10:33
source share

For console applications to work, just add Console.ReadLine() to the end of your code in Main() .

If the user cannot shut down the application, you can do this with the following loop:

 while (true){ Console.ReadLine(); } 
-one
Sep 13 '11 at 13:00
source share



All Articles