Reputation: 715
I have setup a timer:
System.Timers.Timer timer = new System.Timers.Timer (1000);
timer.Enabled = true;
timer.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) => {
timer.Enabled = false;
ui.CldOnPhoneNumberSent(); // <- this method is not fired
};
the second method is not called. if i switch the methods as in:
timer.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) => {
ui.CldOnPhoneNumberSent();
timer.Enabled = false; // <- this method is not called and the timer repeats
}
what's wrong?
Edit: When the method is called from a timer, it's not called completely!:
timer.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) => {
((Timer)sender).Enabled = false;
ui.method1();
};
void method1()
{
do something; //<-- called
do Something; //<-- not called
}
Upvotes: 1
Views: 119
Reputation: 875
As was said in comments, the most likely reason is that your CldOnPhoneNumberSent()
throws some exception preventing further execution.
You should rewrite as follow:
var timer = new System.Timers.Timer (1000);
timer.Elapsed += (sender, args) =>
{
((Timer)sender).Enabled = false;
try
{
ui.CldOnPhoneNumberSent();
}
catch (Exception e)
{
// log exception
// do something with it, eventually rethrow it
}
};
timer.Enabled = true;
Note that is you are inside a WPF application and want to access object created in the UI thread, you may need to dispatch the call:
Action callback = ui.CldOnPhoneNumberSent;
var app = Application.Current;
if (app == null)
{
// This prevents unexpected exceptions being thrown during shutdown (or domain unloading).
return;
}
if (app.CheckAccess())
{
// Already on the correct thread, just execute the action
callback();
}
else
{
// Invoke through the dispatcher
app.Dispatcher.Invoke(callback);
}
As a final note, if you are using .Net 4.5 (with C# 5) you might consider using the async/await pattern instead of System.Timers.Timer, which is easier to use and more readable:
private async Task YourMethod()
{
await Task.Delay(1000)
.ConfigureAwait(continueOnCapturedContext: true); // this makes sure continuation is on the same thread (in your case it should be the UI thread)
try
{
ui.CldOnPhoneNumberSent();
}
catch (Exception e)
{
// log exception
// do something with it, eventually rethrow it
}
}
Upvotes: 0
Reputation: 152654
It could be a problem with variable closure in the anonymous method - try using the sender
value instead of referencing timer
:
timer.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) => {
((Timer)sender).Enabled = false;
ui.CldOnPhoneNumberSent(); // <- this method is not fired
};
Upvotes: 1