我已经设置了一个计时器:
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
};
不调用第二种方法。 如果我按以下方式切换方法:
timer.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) => {
ui.CldOnPhoneNumberSent();
timer.Enabled = false; // <- this method is not called and the timer repeats
}
出了什么问题?
修改 当从计时器调用该方法时,它不会被完全调用!:
timer.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) => {
((Timer)sender).Enabled = false;
ui.method1();
};
void method1()
{
do something; //<-- called
do Something; //<-- not called
}
答案 0 :(得分:1)
匿名方法中的变量闭包可能存在问题 - 尝试使用sender
值而不是引用timer
:
timer.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) => {
((Timer)sender).Enabled = false;
ui.CldOnPhoneNumberSent(); // <- this method is not fired
};
答案 1 :(得分:0)
正如在评论中所说,最可能的原因是你的CldOnPhoneNumberSent()
会引发一些阻止进一步执行的异常。
你应该重写如下:
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;
请注意,如果您在WPF应用程序中并且想要访问在UI线程中创建的对象,则可能需要调度该调用:
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);
}
最后请注意,如果您使用.Net 4.5(使用C#5),您可以考虑使用async/await pattern而不是System.Timers.Timer,它更易于使用且更具可读性:
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
}
}