I have created 2 timers and dispatcherTimer.Interval should be updated in the EventHandler for dispatcherTimer2. I have set a default value for the timer and on running the code I can see that it is getting updated but the EventHandler, dispatcherTimer_Tick is called after the default interval. I am not able to solve this problem.
Where am I going wrong and how do I fix this?
System.Timers.Timer dispatcherTimer = new System.Timers.Timer();
dispatcherTimer.Elapsed += dispatcherTimer_Tick;
System.Timers.Timer dispatcherTimer2 = new System.Timers.Timer();
dispatcherTimer2.Elapsed += dispatcherTimer_Tick2;
dispatcherTimer2.Interval = 10000;
dispatcherTimer2.Start();
dispatcherTimer.Interval = 120000;
dispatcherTimer.Start();
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
VideoPlay.Dispatcher.Invoke(new Action(() =>
{
VideoPlay.Source = new Uri("http://download.wavetlan.com/SVV/Media/HTTP/H264/Talkinghead_Media/H264_test2_Talkinghead_mp4_480x320.mp4");
}));
}
private void dispatcherTimer_Tick2(object sender, EventArgs e)
{
//System.Windows.MessageBox.Show(VideoDay + VideoHr.ToString()+videoMin.ToString());
if(hourparameter==VideoHr && minparameter==videoMin && dayparameter==VideoDay)
{
return;
}
else
{
if (VideoHr == hour)
{
if (day == VideoDay)
{
if (videoMin > min)
{
dispatcherTimer.Enabled = false;
dispatcherTimer = new System.Timers.Timer();
dispatcherTimer.Interval = (videoMin - min) * 60 * 1000;
System.Windows.MessageBox.Show(dispatcherTimer.Interval.ToString());
dispatcherTimer.Enabled = true;
}
EDIT: I have tried with DispatcherTimer again and also checked the times when the EventHandlers are called with some DateTime.Now functions. The problem is still there. if somebody wants I will put up the DispatcherTimer code. I didn't replace the Timers.Timercode in the edit because it would've changed the question. It's basically the same except for the syntax. The code is structured the same way.
EDIT: If I remove the default initialization for the timer interval it just calls the EventHandler continously.But at the same time the 2nd timer eventhandler is also getting called which in turns updates the Interval for the 1st timer. But it never gets used.
I can't understand what I'm doing wrong.
System.Timers.Timer queues ticks in threadpool so you can't be sure that it stops when turn timer's Enabled = false.
You could try to set AutoReset = false at beginning. This makes sure that your timers are run only once but you have start them manually again in the tick code.
dispatcherTimer.AutoReset = false;
dispatcherTimer2.AutoReset = false;
Then you could just replace your timer code with this in dispatcherTimer_Tick2 to fire up timer again.
dispatcherTimer.Interval = (videoMin - min) * 60 * 1000;
dispatcherTimer.Start();
And in the end of dispatcherTimer_Tick also
dispatcherTimer.Start();
I'm not sure what kind behaviour you want but I hope that this helps you.
I would like for my service to be able to initiate communication with other services.
In order for it to act like a client and start the communication, I thought that an initialized in the constructor timer that calls a method every x seconds could be a good idea.
Is it a bad idea?
I can't see what could be wrong with this approach.
You could utilize System.Timers.Timer - https://msdn.microsoft.com/en-us/library/system.timers.timer%28v=vs.110%29.aspx
Set its Interval to value at which you want to raise Elapsed event of timer. Subscribe to Elapsed event using an event handler which you implement, in which you would communicate with the external service.
Edit: simple example
class Program
{
private static void timer_ElapsedEventHandler(object sender, EventArgs e)
{
// communicate to external service
Console.WriteLine("ElapsedEventHandler fired");
}
static void Main(string[] args)
{
var timer = new System.Timers.Timer();
timer.Interval = 3000;
timer.Elapsed += timer_ElapsedEventHandler;
timer.Start();
Console.WriteLine("Timer started");
Console.ReadLine();
}
}
I want to show timer on UI such that when aplication star executing timer starts with 00:00:00 and when it completed its execution timer stops. Timer should show timing per second while running.
You can use the System.Windows.Forms.Timer, which is created for scenarios like yours. You can read more about in MSDN.
You should use the following code snippet as sample:
Timer timer = new Timer();
timer.Interval = 1000;
timer.Tick += new System.EventHandler(timer_Tick);
timer.Start();
private void timer_Tick(object sender, System.EventArgs e)
{
this.Text = string.Format("{0:hh:MM:ss}", DateTime.Now);
}
Notice that you should dispose the Timer when you do not needed.
I am trying to delay events in my method by using a timer, however i do not necessarily understand how to use a timer to wait.
I set up my timer to be 2 seconds, but when i run this code the last call runs without a 2 second delay.
Timer timer = new Timer();
timer.Tick += new EventHandler(timer_Tick); // Everytime timer ticks, timer_Tick will be called
timer.Interval = (1000) * (2); // Timer will tick evert second
timer.Enabled = true; // Enable the timer
void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "first";
timer.Start();
label1.Text = "second";
}
So when i click my button, it immediately shows label1 as "second", as opposed to changing to "first", waiting 2 seconds, then changing to "second". I have read lots of threads here about using timers instead of thread.sleep, but i cannot seem to find/figure out how to actually implement that.
If you're using C# 5.0 await makes this much easier:
private async void button1_Click(object sender, EventArgs e)
{
label1.Text = "first";
await Task.Delay(2000);
label1.Text = "second";
}
timer.Start() just starts the timer but immediately returns while the timer is running in the background. So between setting the label text to first and to second there is nearly no pause. What you want to do is wait for the timer to tick and only then update the label again:
void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
label1.Text = "second";
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "first";
timer.Start();
}
Btw. you should not set timer.Enabled to true, you are already starting the timer using timer.Start().
As mentioned in the comments, you could put the timer creation into a method, like this (note: this is untested):
public void Delayed(int delay, Action action)
{
Timer timer = new Timer();
timer.Interval = delay;
timer.Tick += (s, e) => {
action();
timer.Stop();
};
timer.Start();
}
And then you could just use it like this:
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "first";
Delayed(2000, () => label1.Text = "second");
}
Tergiver’s follow-up
Does using Delayed contain a memory leak (reference leak)?
Subscribing to an event always creates a two-way reference.
In this case timer.Tick gets a reference to an anonymous function (lambda). That function lifts a local variable timer, though it's a reference, not a value, and contains a reference to the passed in Action delegate. That delegate is going to contain a reference to label1, an instance member of the Form. So is there a circular reference from the Timer to the Form?
I don't know the answer, I'm finding it a bit difficult to reason about. Because I don't know, I would remove the use of the lambda in Delayed, making it a proper method and having it, in addition to stopping the timer (which is the sender parameter of the method), also remove the event.
Usually lambdas do not cause problems for the garbage collection. In this case, the timer instance only exists locally and the reference in the lambda does not prevent the garbage collection to collect the instances (see also this question).
I actually tested this again using the .NET Memory Profiler. The timer objects were collected just fine, and no leaking happened. The profiler did give me a warning that there are instances that “[…] have been garbage collected without being properly disposed” though. Removing the event handler in itself (by keeping a reference to it) did not fix that though. Changing the captured timer reference to (Timer)s did not change that either.
What did help—obviously—was to call a timer.Dispose() in the event handler after stopping the timer, but I’d argue if that is actually necessary. I don’t think the profiler warning/note is that critical.
If all you're trying to do is change the text when the timer ticks, would you not be better off putting...
label1.Text = "second";
...In the timer tick, either before or after you change the timer to enabled = false;
Like so;
void timer_Tick(object sender, EventArgs e)
{
timer.Stop();
label1.Text = "second";
}
private void button1_Click(object sender, EventArgs e)
{
label1.Text = "first";
timer.Start();
}
private bool Delay(int millisecond)
{
Stopwatch sw = new Stopwatch();
sw.Start();
bool flag = false;
while (!flag)
{
if (sw.ElapsedMilliseconds > millisecond)
{
flag = true;
}
}
sw.Stop();
return true;
}
bool del = Delay(1000);
I have an experimental project in silverlight, that has no database and scarce resources. Now, I wanted to know if you can prolong or delay the Silverlight loading screen, so I can check what I have modified in the loading page. Problem is, it loads too fast for me to check. I have no data to fetch from the webservice or any resources needed. I'm just experimenting in modifying Silverlight's load page. Can this be done code-wise? Any help would be appreciated. Thanks.
Already found the answer. I just needed a timer for things. thanks for all the queries, anyway
private void Application_Startup(object sender, StartupEventArgs e)
{
var timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(10);
EventHandler eh = null;
eh = (s, args) =>
{
timer.Stop();
this.RootVisual = new Test();
timer.Tick -= eh;
};
timer.Tick += eh;
timer.Start();
}