Correct way to have an endless wait - c#

So I have a program that has a list of timers. Each of the timers has a tick event and lets just say for example, i have 10 timers started (all are in the List).
What is the best way to sit forever (or until i tell it to stop)? Should I just have a while loop?
foreach(Timer t in _timers)
{
t.Start();
}
while(true)
{
Application.DoEvents();
System.Threading.Thread.Sleep(5000);
}
I have a feeling that this isn't the best way...
-- Update
Here's my entire program:
public static void Main()
{
// set some properties and set up the timers
foreach(Timer t in _timers)
{
t.Start();
}
while(true)
{
Application.DoEvents();
System.Threading.Thread.Sleep(5000);
}
}
Thats it. There is no UI, there's nothing else. If I don't have the while loop, then the program just finishes.

Use an EventWaitHandle or array of EventWaitHandles to block thread execution by using the WaitOne() or WaitAll() methods.
http://msdn.microsoft.com/en-us/library/kad9xah9.aspx
So for example
ManualResetEvent mre = new ManualResetEvent(false);
mre.WaitOne();
will wait for eternity.
edit
Since you're making a service, you might want to read this article.

By the Application.DoEvents, I assume you are on a UI thread here. It is never a good idea to keep the UI thread active (even with DoEvents). Why not just start the timers and release control back to the message pump. When the events tick it'll pick up the events.
Why do you want to loop?
Re the update; which Timer are you using? If you use System.Timers.Timer (with the Elapsed event) then it isn't bound to the message-loop (it fires on a separate thread): you can just hang the main thread, perhaps waiting on some exit condition:
using System;
using System.Timers;
static class Program {
static void Main() {
using (Timer timer = new Timer()) {
timer.Interval = 2000;
timer.Elapsed += delegate {
Console.Error.WriteLine("tick");
};
timer.Start();
Console.WriteLine("Press [ret] to exit");
Console.ReadLine();
timer.Stop();
}
}
}

You could wait on a condition variable, or select() on a socket.

Depending on how you're exiting the program, you might consider using only nine timers and have the tenth activity part of the main thread of your code.
Each of those timers is a separate thread and should be handled carefully.
DoEvents is considered 'evil' and should be avoided. http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx

Related

How to create an application loop in C#

I have a console server in C# that keeps running in a while(true) loop. But that takes > 50% CPU even if it is doing nothing. I tried Thread.Sleep it worked! Not eating my CPU anymore but, it do not resumes in the exact time specified and is not considered good practice. Am I doing the right thing? Or is there any other way than using while(true) and Thread.Sleep?
When you want to suspend thread for a while without consuming CPU resources, you usually use some WaitHandle (such as AutoResetEvent or ManualResetEvent) and call it's WaitOne() method to suspend thread until event that is supposed to wake it up occurs (e.g. key is pressed, new network connection arrives, asynchronous operation finishes, etc.).
To wake up thread periodically, you can use timer. I'm not aware of any timer in .NET Framework, that provides WaitHandle (of course you can easily create such class yourself), so have to use Timer and call AutoResetEvent.Set() manually on each tick in it's callback.
private static AutoResetEvent TimerWaitHandle = new AutoResetEvent(false);
static void Main()
{
// Initialize timer
var timerPeriod = TimeSpan.FromMilliseconds(500);
Timer timer = new Timer(TimerCallback, null, timerPeriod, timerPeriod);
while(true)
{
// Here perform your game logic
// Suspend main thread until next timer's tick
TimerWaitHandle.WaitOne();
// It is sometimes useful to wake up thread by more than event,
// for example when new user connects etc. WaitHandle.WaitAny()
// allows you to wake up thread by any event, whichever occurs first.
//WaitHandle.WaitAny(new[] { TimerWaitHandle, tcpListener.BeginAcceptSocket(...).AsyncWaitHandle });
}
}
static void TimerCallback(Object state)
{
// If possible, you can perform desired game logic here, but if you
// need to handle it on main thread, wake it using TimerWaitHandle.Set()
TimerWaitHandle.Set();
}
I can't comment, so i'll put it here.
Theorically with Thread.sleep(1) it won't use that much CPU.
You can get more info from this question/answer: What is the impact of Thread.Sleep(1) in C#?
You can use System.Threading.Timer class. It Provides a mechanism for executing a method on a thread pool thread at specified intervals.
Example
public void Start()
{
}
int dueTime = 1000;
int periodTS = 5000;
System.Threading.Timer myTimer = new System.Threading.Timer(new TimerCallback(Start), null, dueTime, periodTS);
This will call start method after 1 second from calling it and after that start will be called after every 5 second.
You can read more about Timer class here.

Preventing A Thread From Ending

I understand that a Thread will terminate when all of the code it has been assigned is done, but how can I make it so that it stays around waiting for an event? Here is a simple look at my code so you can understand better what my problem is:
public static class TimeUpdater
{
static TimeUpdater()
{
//Initialize the Timer object
timer = new Timer();
timer.Interval = 1000;
timer.Tick += timer_Tick;
}
public static void StartTimer()
{
timer.Start();
}
private static void timer_Tick(object sender, EventArgs e)
{
//Do something
}
}
From the main Thread, here is how I am calling these methods:
Thread timeThread = new Thread(TimeUpdater.StartTimer);
timeThread.Name = "Time Updater";
timeThread.Start();
What this does is it goes inside the StartTimer() method, runs it, and then the thread terminates without ever entering the timer_Tick event handler. If I call StartTimer() from the main thread it works fine.
Anyone can spot the problem? Cheers.
You are starting the timer on a separate thread. Starting a timer is a very fast operation. That's why your thread completes immediately. Tick events are started on the thread-pool asynchronously when the time is due.
If you want a thread wait for something then you should insert code into the thread procedure to wait on something. At the moment you do not wait for anything.
If you want to run the timer procedure, just call it.
Apparently I didn't need to use a Timer object. Here is how I made it work:
public static void StartTimer()
{
while (true)
{
UpdateTime();
Thread.Sleep(1000);
}
}
Thanks for the help guys!
In your StartTimer method you can spin around an infinite loop and call Thread.Sleep to delay execution when needed. I see you have already figured that out though. An alternate idea is to use a timer, but instead of starting it from a worker thread start it from the main thread. You really do not need to be manually creating threads at all here.

Scheduled operations in C# with option to FullStop immediately

I need to do some operations on a certain interval (e.g. from 5 to 5 minutes in a loop) but need to be able to fully stop the thing whenever I want (on push of a button).
I was thinking into using a Timer class but events might fire even after the timer is stopped.
How can I have some code running on a timer and still be able to immediately bring everything to a complete stop?
Just so I am properly understood: By complete stop I mean that events stop and I can dispose of objects like the timer itself etc. I am not asking how to avoid having side effects from unexpected events that are fired after the timer is stopped!
Answer to this question depends a lot on a type of your operations.
Best scenario is to run a thread with a loop and listen to abort event.
static AutoResetEvent abort = new AutoResetEvent();
Thread worker = new Thread(WorkerThread);
void MainThread()
{
worker.Start();
Thread.Sleep(30000);
abort.Set();
}
void WorkerThread()
{
while(true)
{
if(abort.WaitOne(5000)) return;
// DO YOUR JOB
}
}
When you call abort.Set() from another thread, this one will exit.
But if your code is long running, you won't be able to exit until job is done.
To exit immediately you will have to abort thread, but this is not too wise because of resource consumption.
Alternatively, if your operation is long running (let's say you are going through long array), you can check "abort" event state from time to time (every iteration of loop, for example) like this abort.WaitOne(0).
The race condition with the timer is unavoidable since, as you say, the callbacks are executed from the thread pool. However, I believe you can safely dispose the timer even while it's still executing the events. An option which might help is if you consider using the System.Threading.Timer instead of System.Timers.Timer, for which you can call Timer.Dispose(WaitHandle) if you need to have a way to know when the timer events have finished executing. This will prevent race conditions for the cases where you also need to dispose of some other resource - a resource that the event consumer function will attempt to use.
As for the "immediate" requirement, the most immediate would probably be something that uses a synchronization primitive of sorts to stop execution. For example consider this:
static System.Timers.Timer timer;
static void Main(string[] args)
{
var cancelSource = new CancellationTokenSource();
timer = new System.Timers.Timer(200);
timer.Elapsed += new SomeTimerConsumer(cancelSource.Token).timer_Elapsed;
timer.Start();
// Let it run for a while
Thread.Sleep(5000);
// Stop "immediately"
cancelSource.Cancel(); // Tell running events to finish ASAP
lock (timer)
timer.Dispose();
}
class SomeTimerConsumer
{
private CancellationToken cancelTimer;
public SomeTimerConsumer(CancellationToken cancelTimer)
{
this.cancelTimer = cancelTimer;
}
public void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
lock (timer)
{
// Do some potentially long operation, that respects cancellation requests
if (cancelTimer.IsCancellationRequested)
return;
// More stuff here
}
}
}
This is a toy example, but it illustrates my point. The 3 lines that do the "stop immediately" have the following features:
By the time the Dispose call returns, none of the // More stuff here code will ever execute again.
None of the // More stuff here code can execute while the timer is being disposed, because of the lock.
The previous 2 features require the lock, but they prevent the timer from stopping "immediately" because on entering the lock it needs to wait for all timer events calls to finish if they have started. For this reason I added in the cancellation as the fastest way to abort the currently executing events while still guaranteeing that they won't be executing during timer dispose.
Note: if you need multiple timer events to execute simultaneously, consider using a ReaderWriterLockSlim instead of a monitor.
I'd consider one of these two options:
Put a safety check in the events that you need to execute. Something like a database flag. So even if the Timer fails to stop the event will bail out when the safety check fails.
Use something like Quartz.Net for scheduling. This is really heavy handed but it'll do what you want.

Managing threads efficiently in C#

I have an application in which the user will choose to do a number of tasks along with the maximum number of threads. Each task should run on a separate thread. Here is what I am looking for:
If the user specified "n less than t" where n is the maximum number of threads and t is the number of tasks. The program should run "n" threads and after they finish, the program should be notified by some way and repeat the loop untill all tasks are done.
My Question is:
How to know that all running threads has finished their job so that I can repeat the loop.
I recommend using the ThreadPool for your task. Its algorithm will generally be more efficient than something you can roll by hand.
Now the fun part is getting notified when all of your threads complete. Unless you have really specific needs which make this solution unsuitable, it should be easy enough to implement with the CountdownEvent class, which is a special kind of waithandle that waits until its been signaled n times. Here's an example:
using System;
using System.Linq;
using System.Threading;
using System.Diagnostics;
namespace CSharpSandbox
{
class Program
{
static void SomeTask(int sleepInterval, CountdownEvent countDown)
{
try
{
// pretend this did something more profound
Thread.Sleep(sleepInterval);
}
finally
{
// need to signal in a finally block, otherwise an exception may occur and prevent
// this from being signaled
countDown.Signal();
}
}
static CountdownEvent StartTasks(int count)
{
Random rnd = new Random();
CountdownEvent countDown = new CountdownEvent(count);
for (int i = 0; i < count; i++)
{
ThreadPool.QueueUserWorkItem(_ => SomeTask(rnd.Next(100), countDown));
}
return countDown;
}
public static void Main(string[] args)
{
Console.WriteLine("Starting. . .");
var stopWatch = Stopwatch.StartNew();
using(CountdownEvent countdownEvent = StartTasks(100))
{
countdownEvent.Wait();
// waits until the countdownEvent is signalled 100 times
}
stopWatch.Stop();
Console.WriteLine("Done! Elapsed time: {0} milliseconds", stopWatch.Elapsed.TotalMilliseconds);
}
}
}
You probably want to use a Thread Pool for this. You (can) specify the number of threads in the pool, and give it tasks to do. When a thread in the pool is idle, it automatically looks for another task to carry out.
If you want to do this without the thread pool, you can use Thread.Join to wait for the threads to complete. That is:
Thread t1 = new Thread(...);
Thread t2 = new Thread(...);
t1.Start();
t2.Start();
// Wait for threads to finish
t1.Join();
t2.Join();
// At this point, all threads are done.
Of course, if this is an interactive application you'd want that to happen in a thread itself. And if you wanted to get fancy, the waiting thread could do the work of one of the threads (i.e. you'd start thread 1 and then the main thread would do the work of the second thread).
If this is an interactive application, then you probably want to make use of BackgroundWorker (which used the thread pool). If you attach an event handler to the RunWorkCompleted event, then you will be notified when the worker has completed its task. If you have multiple workers, have a single RunWorkCompleted event handler, and keep track of which workers have signaled. When they've all signaled, then your program can go ahead and do whatever else it needs to do.
The example at http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx should give you a good start.
Could you check the isAlive() value for each thread? if all values equal false then you would know that all your threads have ended. Additionally, there is a way to have your delegate return it's own status.
http://msdn.microsoft.com/en-us/library/system.threading.thread.isalive(v=VS.90).aspx

How do I let main thread suspend and wait for the System.Timer.Timer running

Hi I am using System.Timer.Timer
I always get NULL after running my programme and it only works if I add this.sleep(6000). Suppose the reason is the main thread ends but the timer hasn't finished ...
Here is the class and I call the class from my main form.
Class class1
{
string finalResult = "";
public string getNumber()
{
RunTimer();
return finalResult;
}
pubic void RunTimer ()
{
timer = new System.Timers.Timer(30000);
timer.Interval = 1000;
timer.Elapsed += new System.Timers.ElapsedEventHandler(cal);
timer.Start();
}
private void cal(object sender,System.Timers.ElapsedEventArgs e)
{
finalResult += READFROMCOMPORT;
}
}
A good rule of thumb is to never use Thread.Sleep in production code. Its presence usually indicates poor threading design.
Instead, listen to the COM Port's DataReceived event.
Why would you want to use a timer in this instance?
If you want this to be a synchronous operation and wait for finalresult to get populated, you could just wait 6 seconds before returning READFROMCOMPORT.
EDIT: If you need the program to continue running, you could create a callback event that you bind to after you instantiate the class. Once the timer expires, you can raise the callback event and pass your new value
EDIT 2: an easy way to implement this sort of asynchronous'ness is to use a BackgroundWorker component. the backgroundworker has a DoWork() method which contains your asynchrnous code, as well as a "RunWorkerCompleted" callback event which you can subscribe to to get your asynchronous result. See here for more: http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
If you're already calling GetNumber() from a separate thread from the GUI, ditch the timer, do the work in GetNumber(), and the thread will stop returning early. In any case, don't use Thread.Sleep because there's no way to unblock it if you need to, or if the app quits. Use Monitor.Wait instead, which can be unblocked with Monitor.Pulse.
Use TimerCallback
http://www.gnu.org/software/dotgnu/pnetlib-doc/System/Threading/Timer.html

Categories