I am currently working on a c# project where I need to perform a task so many times every so many seconds.
For example, write to the console 5 times every 1 second. How could I go about doing this.
Thanks for any help you can provide.
You can use a Timer and bind and event to the Timer.Elapsed event.
using System.Timers;
Sample code:
Timer timer = new Timer();
timer.Elapsed += (sender, eventArgs) =>
{
for (int i = 0; i < 5; i++)
{
Console.Write(i);
}
};
Is this an console application, or do you run this on another thread?
For short stuff like this, use a timer. There are two main ones to choose from:
System.Threading.Timer
And:
System.Windows.Forms.Timer
The former uses the ThreadPool, the latter uses UI events. They both expose the ability to specify and interval and either a callback method or event to attach to in order to put custom code.
For longer periods of inactivity, look into scheduling either with the Windows scheduler (the OS one) or a scheduling framework such as Quartz.NET.
Do note that the accuracy of the timers vary, but not really within margins that humans can detect :-)
Also note that the callback of the threaded timer will return on an arbitrary ThreadPool thread, so you could effectively end up "multi-threading" the code without realising it.
There is also System.Timers.Timer, it exposes an event. An article about the different timers available can be found here.
I don't think it will affect you, but it's still worth knowing - windows is not a real-time OS; if you ask for something to be done every X milliseconds, it won't be exact, as for how much it will be out depends on a variety of things.
You could create a thread to do it. Especially useful if you want to do a lot of processing! Here's an example of a thread doing work every 1s (1000ms):
public void Start()
{
running = true;
thread = new Thread(new ParameterizedThreadStart(ThreadFunction));
thread.Start();
}
public virtual void ThreadFunction(object o)
{
var insert = false;
while (running)
{
//Do work
Thread.Sleep(1000);
}
}
try this
While (true)
{
for (int i=0; i<5; i++)
{
console ("Hello");
}
//this will pause for 1 sec (1000msec)
Thread.sleep(1000);
}
Related
I'm incredibly new to programming, and I've been learning well enough so far, I think, but I still can't get a grasp around the idea of making a delay the way I want. What I'm working on is a sort of test "game" thingy using a Windows forms application that involves a combat system. In it, I want to make an NPC that does an action every couple of seconds. The problem is, I also want to allow the player to interact between attacks. Thread.sleep really doesn't seem to work for me not only because I don't know how to multithread, but whenever I try to run it, say, like this:
textBox1.Text += "\r\nThread Sleeps!";
System.Threading.Thread.Sleep(4000);
textBox1.Text += "\r\nThread awakens!";
It seems to insist on sleeping first, then printing both lines.
I think that's all I can say at the moment, but if that's still too vague or wordy, feel free to tell me.
In short, In C# I want to make something delay before running but at the same time still allow user interaction.
If you're using .NET 4.5 you can use the new async/await framework to sleep without locking the thread.
How it works is that you mark the function in need of asynchronous operations, with the async keyword. This is just a hint to the compiler. Then you use the await keyword on the line where you want your code to run asynchronously and your program will wait without locking the thread or the UI. The method you call (on the await line) has to be marked with an async keyword as well and is usually named ending with Async, as in ImportFilesAsync.
What you need to do in your example is:
Make sure your program has .Net Framework 4.5 as Target Framework
Mark your function that needs to sleep with the async keyword (see example below)
Add using System.Threading.Tasks; to your code.
Your code is now ready to use the Task.Delay method instead of the System.Threading.Thread.Sleep method (it is possible to use await on Task.Delay because Task.Delay is marked with async in its definition).
private async void button1_Click(object sender, EventArgs e)
{
textBox1.Text += "\r\nThread Sleeps!";
await Task.Delay(3000);
textBox1.Text += "\r\nThread awakens!";
}
Here you can read more about Task.Delay and Await.
By adding using System.Timers; to your program you can use this function:
private static void delay(int Time_delay)
{
int i=0;
// ameTir = new System.Timers.Timer();
_delayTimer = new System.Timers.Timer();
_delayTimer.Interval = Time_delay;
_delayTimer.AutoReset = false; //so that it only calls the method once
_delayTimer.Elapsed += (s, args) => i = 1;
_delayTimer.Start();
while (i == 0) { };
}
Delay is a function and can be used like:
delay(5000);
Sorry for awakening an old question like this.
But I think what the original author wanted as an answer was:
You need to force your program to make the graphic update after you make the change to the textbox1. You can do that by invoking Update();
textBox1.Text += "\r\nThread Sleeps!";
textBox1.Update();
System.Threading.Thread.Sleep(4000);
textBox1.Text += "\r\nThread awakens!";
textBox1.Update();
Normally this will be done automatically when the thread is done.
Ex, you press a button, changes are made to the text, thread dies, and then .Update() is fired and you see the changes.
(I'm not an expert so I cant really tell you when its fired, but its something similar to this any way.)
In this case, you make a change, pause the thread, and then change the text again, and when the thread finally dies the .Update() is fired. This resulting in you only seeing the last change made to the text.
You would experience the same issue if you had a long execution between the text changes.
You can probably use timers : http://msdn.microsoft.com/en-us/library/system.timers.timer.aspx
Timers can provide you a precision up to 1 millisecond. Depending on the tick interval an event will be generated. Do your stuff inside the tick event.
private void WaitNSeconds(int seconds)
{
if (seconds < 1) return;
DateTime _desired = DateTime.Now.AddSeconds(seconds);
while (DateTime.Now < _desired) {
Thread.Sleep(1);
System.Windows.Forms.Application.DoEvents();
}
}
so when i try and press "button 2" I expect two things to happen a)"dowsomething" is suppose to do its thing in the "now" class. b) Whilst its doing something i want it to count how long that something takes. However because "dosomething" is program hungry Form1 freezes and it wont run the timer. Im a bit of a rookie at c# so I wouldn't know how to run it in the background. So any outside the box ideas? Thanks.
int time = 0;
private void button2_Click(object sender, EventArgs e)
{
timer1.Start();
nowthen now = new nowthen();
now.dosomething(withthis); //This task is program hungry and causes the form to freeze
timer1.Stop();
time = 0;
}
private void timer1_Tick(object sender, EventArgs e)
{
time = time + 1;
label2.Text = time.ToString();
label2.Refresh();
}
In Windows Forms, all of your UI stuff runs on one thread. That includes the timer - the timer is implemented behind the scenes with windows messages.
Your question is actually two questions:-
How can I time an operation in C# / Windows forms?
How to time something depends on the precision you're looking for. For accuracy in the region of +/- 10ms then you can use Environment.TickCount - store it's value before your operation, then get the value again after, and subtract the stored value - and you have your duration.
More precise is the Stopwatch class in System.Threading - see http://www.dotnetperls.com/stopwatch
How can I run a task "in the background" ?
To run your operation in the background, you need to run it in a different thread. The easiest, designed friendly (but perhaps not all that flexible way) is to use the BackgroundWorker component. This wraps using a worker thread to do an operation for you. See http://www.dotnetperls.com/backgroundworker for a good explanation of how to do that.
More advanced, and more flexible, is to create your own thread to do the work. However, that will create some important issues to consider around how to syncronize what's going on - as soon as you start your thread, your method call finishes (it's asyncronous) and you need to have a mechanism for notifiying your UI code that the process has finished. This example seems as good as any on how to create your own thread: http://www.daveoncsharp.com/2009/09/create-a-worker-thread-for-your-windows-form-in-csharp/
For .NET 4 use:
Task.Factory.StartNew((Action) delegate()
{
// this code is now executing on a new thread.
nowthen now = new nowthen();
now.dosomething(withthis);
// to update the UI from here, you must use Invoke to make the call on UI thread
textBox1.Invoke((Action) delegate()
{
textBox1.Text = "This update occurs on the UI thread";
});
});
If you just want to time how long something takes, use System.Diagnostics.Stopwatch.
Stopwatch sw = Stopwatch.StartNew();
nowThen = new nowThen();
no.dosomething(withthis);
sw.Stop();
// you can get the time it took from sw.Elapsed
That won't, however, update a label with the elapsed time.
I guess I'll throw this in too, although it's not as elegant looking as #paul's solution.
timer1.Start();
var bw = new BackgroundWorker();
bw.DoWork += (s, e) => { now.dosomething((myArgumentType)e.Argument); };
bw.RunWorkerCompleted += (s, e) => { timer1.Stop(); };
bw.RunWorkerAsync(withthis);
This starts your timer, creates a new BackgroundWorker thread, tells it what to run in the DoWork method (dosomething runs in a separate thread), then stops the timer in the RunWorkerCompleted method (after dosomething is finished, control returns to the main thread in RunWorkerCompleted).
I am hitting a wall and have come here hoping you guys can help me out with the following:
I am designing a wp7 app where I am having sounds fire off periodically (every 700 ms). I want these sounds to play on another thread than the UI thread. Thus, I cannot use a dispatch timer because the UI thread will be heavily used in the meantime while these sounds fire.
In looking at this problem, I made a backgroundworker with a Thread.Sleep(700) command. This works, but as one may expect it can take longer than 700 ms to fire off a sound. So sometimes I hear delays.
So I turn to you guys -- How can I get as close to a firing of a sound every 700 ms in a backgroundworker or another thread? Is a Timer a wise idea?
Here is some code to better illustrate:
private void RunBackgroundWorker()
{
backgroundWorker = new BackgroundWorker ();
backgroundWorker.WorkerSupportsCancellation = true;
backgroundWorker.DoWork += new DoWorkEventHandler(StartSounds);
backgroundWorker.RunWorkerAsync();
}
public void StartSounds(object sender, EventArgs e)
{
for (currentsoundchoice = 0; currentsoundchoice <= max; currentsoundchoice ++)
{
if (backgroundWorker.CancellationPending == true)
{
backgroundWorker.CancelAsync();
currentsoundchoice = max + 1; //just to ensure it stops.
}
else
{
Time_Tick();
if (max == 12)
currentsoundchoice = -1; //repeats the loop when it reaches max.
}
}
}
void Time_Tick()
{
Thread.Sleep(700);
FrameworkDispatcher.Update();
switch (sounds)
case 0: //code
break;
// ETC, So forth.......
}
I heard that using a Timer is also a good way to go about this, but is it possible to run a timer in a backgroundworker, and if so, how would it be structured? More importantly, would it allow me to get as close to the 700 ms firing time I desire without any audible delays?
Thank you.
BackgroundWorker is the wrong choice here. It is designed to allow you to perform expensive work on a background thread and then synchronize the results back to the UI. You do not need any synchronization. Moreover, you need the work to occur at a regular interval - not as a one-off task.
A Timer would be much more suited. It would allow you to run your logic every 700ms and to remove the nasty Thread.Sleep() call you have in your current code. The Timer will use a background thread just like BackgroundWorker does.
Note, however, that it can only guarantee that it won't run before 700ms has elapsed. If you're absolutely hammering the device, for example, it may struggle to run your code on a regular interval and you may notice lag.
I have an issue with the System.Timers.Timer object. I use the timer object to perform a task at regular intervals. In the timer constructor I call the method doing the work ( DoTimeCheck() ), to ensure that the task is run once at startup also. The work (at regular intervals) is done in a BackgroundWorker.
I call the timer with this:
UpdaterTimer ut = UpdaterTimer.UpdaterTimerInstance;
My problem is that I need to delay the first run of the task with 3 minutes(the one that runs at application startup). Subsequent runs (Elapsed event) should run without delay. I thought of doing this by calling
System.Threading.Thread.Sleep(TimeToDelayFirstRunInMiliseconds);
but this fails, because it also hangs the UI of the app (main thread) making it unusable. How can I delay the first run of DoTimeCheck() without hanging the UI?
The code of the timer is below. If the issue is not presented in a clear manner please let me know and I will edit. Thank you in advance.
public sealed class UpdaterTimer : Timer
{
private static readonly UpdaterTimer _timer = new UpdaterTimer();
public static UpdaterTimer UpdaterTimerInstance
{
get { return _timer; }
}
static UpdaterTimer()
{
_timer.AutoReset = true;
_timer.Interval = Utils.TimeBetweenChecksInMiliseconds;
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Start();
DoTimeCheck();
}
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
DoTimeCheck();
}
private static void DoTimeCheck()
{
//... work here
}
}
One way of doing this would be to give the Timer Interval an initial value (e.g. 3 minutes). Then, in your Elapsed event handler, you could change the interval to your regular value which will be used from then on.
_timer.Interval = Utils.InitialCheckInterval;
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
if (_timer.Interval == Utils.InitialCheckInterval)
{
_timer.Interval = Utils.RegularCheckInterval;
}
DoTimeCheck();
}
It appears (although you've not shown that code) that you're calling Sleep(TimeToDelayFirstRunInMiliseconds); on the main/GUI thread, so that's what's causing your UI thread to hang. Instead, you should set your timer to be delayed by 3 minutes on the first run, then once it runs you change the timer again to run at the frequency you desire for all the subsequent runs.
Your UI resides on the same thread, so when you put the thread to sleep, it will cause your UI to hang as well. You need to run the timer on a different thread.
You're already using timers fine it seems. Just use another one to do a three minute delay before you start up your other timer.
timer = new Timer();
timer.AutoReset = false;
timer.Interval = 3*60*1000;
timer.Elapsed += startOtherTimerMethod;
timer.Start();
Edit: I should note that this is much the same as Peter Kelly's answer except that his solution is more elegant since it uses just one timer, no extra methods and takes advantage of the fact that the timer is changeable between runs. If you liked this answer, you'll love his. ;-)
Your UI needs a seperate thread, currently you are also sleeping the UI. Check this post.
You should not use thread.sleep in this situation you should use the winforms control
BackgroundWorker which never locks the main UI. You can write your logic there.
example here:
http://www.knowdotnet.com/articles/backgroundworker.html
Use a System.Threading.Timer - the constructor takes a parameter for the delay of the first run and an interval for the subsequent runs.
If I have a Windows Service that needs to execute a task every 30 seconds which is better to use; the Timer() class or a loop that executes the task then sleeps for a number of seconds?
class MessageReceiver
{
public MessageReceiver()
{
}
public void CommencePolling()
{
while (true)
{
try
{
this.ExecuteTask();
System.Threading.Thread.Sleep(30000);
}
catch (Exception)
{
// log the exception
}
}
}
public void ExecutedTask()
{
// do stuff
}
}
class MessageReceiver
{
public MessageReceiver()
{
}
public void CommencePolling()
{
var timer = new Timer()
{
AutoReset = true,
Interval = 30000,
Enabled = true
};
timer.Elapsed += Timer_Tick;
}
public void Timer_Tick(object sender, ElapsedEventArgs args)
{
try
{
// do stuff
}
catch (Exception)
{
// log the exception
}
}
}
The windows service will create an instance of the MessageReciever class and execute the CommencePolling method on a new thread.
I think it really depends on your requirement.
case 1.
Suppose you want to run this.ExecuteTask() every five minutes starting from 12:00AM (i.e., 12:00, 12:05, ...) and suppose the execution time of this.ExecuteTask() varies (for example, from 30 sec to 2 min), maybe using timer instead of Thread.Sleep() seems to be an easier way of doing it (at least for me).
However, you can achieve this behavior with Thread.Sleep() as well by calculating the offset while taking timestamps on a thread wake-up and on a completion of this.ExecuteTask().
case 2.
Suppose you want to perform the task in the next 5 min just after completion of this.ExecuteTask(), using Thread.Sleep() seems to be easier. Again, you can achieve this behavior with a timer as well by reseting the timer every time while calculating offsets on every time this.ExecuteTask() completes.
Note1, for the case 1, you should be very careful in the following scenario: what if this.ExecuteTask() sometimes takes more than the period (i.e. it starts at 12:05 and completes 12:13 in the example above).
What does this mean to your application and how will it be handled?
a. Total failure - abort the service or abort the current(12:05) execution at 12:10 and launch 12:10 execution.
b. Not a big deal (skip 12:10 one and run this.ExecuteTask() at 12:15).
c. Not a big deal, but need to launch 12:10 execution immediately after 12:05 task finishes (what if it keeps taking more than 5 min??).
d. Need to launch 12:10 execution even though 12:05 execution is currently running.
e. anything else?
For the policy you select above, does your choice of implementation (either timer or Thread.Sleep()) easy to support your policy?
Note2. There are several timers you can use in .NET. Please see the following document (even though it's bit aged, but it seems to be a good start): Comparing the Timer Classes in the .NET Framework Class Library
Are you doing anything else during that ten second wait? Using Thread.sleep would block, preventing you from doing other things. From a performance point of view I don't think you'd see too much difference, but I would avoid using Thread.sleep myself.
There are three timers to choose from - System.Windows.Forms.Timer is implemented on the main thread whereas System.Timers.Timer and System.Threading.Timer are creating seperate threads.
I believe both methods are equivalent. There will be a thread either way: either because you create one, or because the library implementing the Timer class creates one.
Using the Timer class might be slightly more less expensive resource-wise, since the thread implementing timers probably monitors other timeouts as well.
I this the answers to this question will help.
Not answered by me but John Saunders (above)... the answer can be found here For a windows service, which is better, a wait-spin or a timer?