Still getting my head wrapped around Timers in C# which are a LOT more powerful than in AS3.
I need to call another method at shorter and shorter intervals. Say once a second in the beginning, then gradually shorter intervals until maybe I am calling the method 100X a second.
I've used coroutines but pretty sure I need an actual Timer object. Can anyone help or point in the right direction?
You can start with this example:
System.Timers.Timer t = new System.Timers.Timer();
public void TimerSetup()
{
t.Interval = 1000;
t.Elapsed += ElapsedMethod;
t.Start();
}
public void ElapsedMethod(object sender, System.Timers.ElapsedEventArgs e)
{
//do stuff
t.Interval = t.Interval - 5; //however much you want it to reduce.
}
You will have to determine the conditions that you need for reducing the timer interval, and when to do it, but this should give you a start.
Using a Task:
shouldIStayInThisLoop = true;
interval = 1000; // 1000 milliseconds == 1 second
Task.Factory.StartNew(()->
{
while (shouldIStayInThisLoop)
{
DoSomeStuff();
if (SomeConditionIsMet())
{
interval = GetNewInterval();
}
Thread.Sleep(interval);
shouldIStayInThisLoop = CheckIfIShouldStayInThisLoop();
}
});
Related
I have a function in winform that is executed every x time (eg. every 60 minutes).
And then it does some stuff, then I want it to wait some seconds (using a timer) and then execute do some stuff part2.
private void goToFtp(int time)
{
double interval = time* 60 * 1000;
System.Timers.Timer checkForTime = new System.Timers.Timer(interval);
checkForTime.Elapsed += new ElapsedEventHandler(checkForTime_Elapsed);
checkForTime.Enabled = true;
}
System.Windows.Forms.Timer timerDelayWatcher = new System.Windows.Forms.Timer();
private void checkForTime_Elapsed(object sender, ElapsedEventArgs e)
{
.......Do some stuff part1
timerDelayWatcher.Tick += new EventHandler(timerDelayWatcher_Tick); // Everytime timer ticks, timer_Tick will be called
timerDelayWatcher.Interval = (1000) * (5);
timerDelayWatcher.Enabled = true;
timerDelayWatcher.Start();
}
private void timerDelayWatcher_Tick(object sender, EventArgs e)
{
timerDelayWatcher.Stop();
.......Do some stuff part2
}
The problem is that the timerDelayWatcher_Tick is not fired...any ideias why?
You need use:
Thread.Sleep(5000);
But first you need add
using System.Threading;
or use
System.Threading.Thread.Sleep(5000);
on 5000 are the time in milliseconds
Sample
private void timerDelayWatcher_Tick(object sender, EventArgs e)
{
timerDelayWatcher.Stop();
System.Threading.Thread.Sleep(5000);
.......Do some stuff part2
}
Try calling the start method on the system.timers.timer firstly, and I would recommend sticking to one type of timer, and pattern of use, say use the system.timer.timer and do the work you need on elapsed, then restart with and wait for the next elapsed event.
Either that or I would suggest looking at the task library and async flow in .net 4/4.5 and as #Ferri suggests using a Sleep
Take also care on loosing reference to the class containing the timerDelayWatcher member.
If it happens the timer is disposed so no more events...
I'm considering use Task.Delay() for a non-stop timer, because it's more simple and readable.
As I'm new to .NET, I see no significant difference between the two codes. Can you show me the difference (if there is any) between them?
// Create variable at some place
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(5);
timer.Tick += timer_Elapsed;
timer.Start();
// Function other place
void timer_Elapsed(object sender, EventArgs e)
{
//Do stuff
}
vs
// Every thing inside a function
async void TaskTimer()
{
while (true)
{
await Task.Delay(5000);
// Do stuff
}
}
There are two major differences:
The Task.Delay approach will delay the specified amount of time between cycles, while the DispatcherTimer approach will start a new cycle on the specified cycle time.
Task.Delay is more portable, since it does not depend on a type tied to a specific UI.
I have a windows 8 game app that uses a timer for each level and I am trying to the timer 3 seconds.
The code I have to start the timer works but I can't seem to delay the timer so that I display words to count it down.
Here is the code:
private async void timer_Tick(object sender, object e)
{
await
Time.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Low,
() =>
{ Time.Text = string.Format("{0}:{1}", (Counter/60), (Counter%60).ToString().PadLeft(2, ' ')); });
Counter--;
await Task.Delay(3000);}}
so I put async there because I thought I should put await Task.Delay(3000); after counter to delay the timer but it doesn't work. I do not want to the WinRT Xaml toolkit countdown timer because I don't want the animation there.
Any suggestions on what I am doing wrong would be great!
So presumably you want to update the display every second, to get this countdown? But if I've understood, for some reason you want to delay everything by 3 seconds.
If you want things to happen 3 seconds later than they're currently happening, the obvious solution is to program the timer so it calls you when you actually want it to:
private DispatcherTimer t = new DispatcherTimer();
private int Counter = 120;
public MainPage()
{
InitializeComponent();
t.Interval = TimeSpan.FromSeconds(4);
t.Tick += timer_Tick;
t.Start();
}
private void timer_Tick(object sender, object o)
{
t.Interval = TimeSpan.FromSeconds(1);
Time.Text = string.Format("{0}:{1}", (Counter / 60), (Counter % 60).ToString().PadLeft(2, ' '));
Counter--;
}
That makes the first tick take 4 seconds to arrive, and then adjusts the interval to 1 second. So you'll get ticks spaced at 1 second intervals, but everything will happen 3 seconds later than it otherwise would. (If set the tick interval to 1 initially, then the first tick would take 1 second to arrive, which is why you need a delay of 4 seconds initially - an initial tick of 3 would only delay things by 2 seconds.)
However, if you need to do some things immediately, and some with a delay, one obvious way to do that would be just to adjust the count in your handler by 3 seconds:
private const int LevelMaxTime = 120;
private DispatcherTimer t = new DispatcherTimer();
private int Counter = LevelMaxTime;
public MainPage()
{
InitializeComponent();
t.Interval = TimeSpan.FromSeconds(1);
t.Tick += timer_Tick;
t.Start();
}
private void timer_Tick(object sender, object o)
{
// Do the undelayed work here, whatever that is...
// Next, we do the delayed work, if there is any yet.
int effectiveCount = Counter + 3;
if (effectiveCount <= LevelMaxTime)
{
Time.Text = string.Format("{0}:{1}", (effectiveCount / 60), (effectiveCount % 60).ToString().PadLeft(2, ' '));
}
Counter--;
}
This just takes the effective current time to be 3 seconds before what Current says it is, thus delaying everything by 3 seconds.
You could do something more like your original code:
private async void timer_Tick(object sender, object o)
{
// Wait for 3 seconds...for some reason
await Task.Delay(TimeSpan.FromSeconds(3));
Time.Text = string.Format("{0}:{1}", (Counter / 60), (Counter % 60).ToString().PadLeft(2, ' '));
Counter--;
}
That's closer in spirit to what you wrote (as far as I can tell), only it works, but it seems unnecessarily convoluted. Why not just program the timer to call you at the right time, rather than getting callbacks at the wrong time and then trying to compensate? It's a timer. It'll call you when you tell it to!
I created windows service on C#.
For now I have methods for scanning DB.
I need call this method two times per minute. Actually I don't know method for waiting in windows service.
I tried Thread.Sleep... but nothing happened.
Please help me with this problem.
private int wait;
protected void Start()
{
wait = 1000;
while (true)
{
if (wait < 30000)
wait += wait;
//implement logic for waiting
Video video = new Video();
video.FindFileForConvert();
if (video.Path != null)
{
Console.WriteLine("video != null. video path = {0}", video.Path);
video.BeginConvertation();
video.DeleteOriginFile();
wait = 1000;
}
}
}
You should use System.Threading.Timer for the same. Since Thread.sleep is not a good practice atleast in some cases.
You may use Timer
public static int Main() {
/* Adds the event and the event handler for the method that will
process the timer event to the timer. */
myTimer.Tick += new EventHandler(TimerEventProcessor);
// Sets the timer interval to 5 seconds.
myTimer.Interval = 5000;
myTimer.Start();
// Runs the timer, and raises the event.
while(exitFlag == false) {
// Processes all the events in the queue.
Application.DoEvents();
}
return 0;
}
I may be mistaken, but I think that this code will help you resolve your problem. DispatcherTimer
DispatcherTimer dispathcerTimer = new DispatcherTimer();
dispathcerTimer.Interval = TimeSpan.FromMinutes(2);
dispathcerTimer.Tick += dispathcerTimer_Tick;
dispathcerTimer.Start();
void dispatcherTime_Tick(object sender, object e)
{
//function, which needs to be invoked every two minutes.
}
I have two alternative using timer or using sleep, I need to call a method every 3 seconds after this method is finished, I wrote basic example to demonstrate what I mean:
public static void Main()
{
new Thread(new ThreadStart(fooUsingSleep)).Start();
callToMethodAfterInterval(new Action<object, ElapsedEventArgs>(fooUsingTimer), 3000);
}
public static void fooUsingSleep()
{
Console.WriteLine("Doing some consuming time work using sleep");
Thread.Sleep(3000);
fooUsingSleep();
}
public static void fooUsingTimer(object dummy, ElapsedEventArgs dummyElapsed)
{
Console.WriteLine("Doing some consuming time work usning timer");
callToMethodAfterInterval(new Action<object, ElapsedEventArgs>(fooUsingTimer), 3000);
}
public static void callToMethodAfterInterval(Action<object,ElapsedEventArgs> inMethod, int inInterval)
{
System.Timers.Timer myTimer = new System.Timers.Timer();
myTimer.Elapsed += new ElapsedEventHandler(inMethod);
myTimer.Interval = inInterval;
myTimer.AutoReset = false;
myTimer.Start();
}
So my questions are
1)Can I wrote the code with the timer more elegant? Means removing the call to the callToMethodAfterInterval method from fooUsingTimer, make the timer one or two lines, and remove the dummy variables from the declaration of fooUsingTimer?
2)I understand sleep isn't busy waiting (http://www.codeproject.com/KB/threads/ThreadingDotNet.aspx)
So I don't found justification to use the timer option here, because the sleep is more simple, what is better to use, the timer version or the sleep one?
3)I know that Timers.timer is thread safe, does it can help me in the behavior I want to implement?
Thanks.
Do you realize that fooUsingSleep is calling itself over and over? It will eventually generate a stack overflow.
If you are using timer, it can be as simple as this:
System.Windows.Forms.Timer t = new System.Windows.Forms.Timer();
t.Interval = 3000;
t.Tick += new EventHandler((o,ea) => Console.WriteLine("foo"));
The real context of your program matters too.
The sleep option 'wastes' a Thread, not a problem in a small console app but in general not a good idea.
You don't need to restart the timer, the following will keep ticking:
static void Main(string[] args)
{
var t = new System.Timers.Timer(1000);
t.Elapsed += (s, e) => CallMeBack();
t.Start();
Console.ReadLine();
}
Sleep will do the trick, Timer on the other hand has been designed for that exact purpose, conventions are better and they will usually make your code more understandable.