在 Timer 内启动 Viewmodel 已过去但不起作用
Launching a Viewmodel inside a Timer elapsed not working
我正在尝试在计时器事件中启动另一个视图模型。当我跳过这个计时器事件时,似乎启动器使用得很好。但是,如果启动是在活动期间完成的,则不会。有人可以看看问题出在哪里吗?
using System.Timers;
using Caliburn.Micro.Xamarin.Forms;
using MyProject.Resources;
using System.Windows.Input;
using Xamarin.Forms;
using System.Diagnostics;
namespace MyProject.ViewModels
{
public class PairingDeviceViewModel : BaseScreen {
public INavigationService NavigationService { get; set; }
private Timer timer;
private const float MAX = 20;
private string percentage;
private float rate;
public float Rate { get => rate; set => Set(ref rate, value); }
public string Percentage { get => percentage; set => Set(ref percentage, value); }
protected override void OnInitialize()
{
base.OnInitialize();
timer = new Timer
{
Interval = MAX,
};
}
protected override void OnActivate()
{
base.OnActivate();
timer.Elapsed += Timer_Elapsed;
timer.Start();
}
protected override void OnDeactivate(bool close)
{
base.OnDeactivate(close);
timer.Elapsed -= Timer_Elapsed;
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
Debug.WriteLine($"Timer_Elapsed");
Debug.WriteLine($"Rate {Rate}");
Rate++;
Percentage = string.Format(StringResources.PercentageNumber, Rate);
NotifyOfPropertyChange(() => Percentage);
if (Rate == MAX)
{
timer.Stop();
Debug.WriteLine($"navigation begins");
NavigationService.NavigateToViewModelAsync<ConfigurationListViewModel>();
}
Debug.WriteLine($"Timer_Elapsed END");
}
public ICommand SkipBluetoothScanning => new Command(() => {
timer.Stop();
NavigationService.NavigateToViewModelAsync<ConfigurationListViewModel>();
});
}
所以在我的 Timer_elapsed
方法中,一旦 Rate
等于 MAX
,我就会调用 NavigationService.NavigateToViewModelAsync<>..
。这个问题是这个条件 Rate==MAX
被调用了不止一次。
请查看日志文件。
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Timer_Elapsed END
Timer_Elapsed
Rate 11
Timer_Elapsed END
Timer_Elapsed
Rate 12
Timer_Elapsed END
Timer_Elapsed
Rate 13
Timer_Elapsed END
Timer_Elapsed
Rate 14
Timer_Elapsed END
Timer_Elapsed
Rate 15
Timer_Elapsed END
Timer_Elapsed
Rate 16
Timer_Elapsed END
Timer_Elapsed
Timer_Elapsed END
Rate 17
Timer_Elapsed
Rate 18
Timer_Elapsed END
Timer_Elapsed
Rate 19
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
Timer_Elapsed END
[InputMethodManager] HSIFW - flag : 0 Pid : 6116
[InputMethodManager] HSIFW - flag : 0 Pid : 6116
Timer_Elapsed END
Timer_Elapsed END
Timer_Elapsed END
Timer_Elapsed END
Timer_Elapsed END
Timer_Elapsed END
[InputMethodManager] HSIFW - flag : 0 Pid : 6116
[InputMethodManager] HSIFW - flag : 0 Pid : 6116
Timer_Elapsed END
Timer_Elapsed END
[InputMethodManager] HSIFW - flag : 0 Pid : 6116
Timer_Elapsed END
Timer_Elapsed END
[InputMethodManager] HSIFW - flag : 0 Pid : 6116
Timer_Elapsed END
DispatcherTimer
是否是此功能或其他功能的更好解决方案?
非常感谢。
您可以像这样锁定线程以避免重复执行:
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (this)
{
if (Math.Abs(Rate - MAX) < double.Epsilon){
//something you want to do
...
}
}
}
我正在尝试在计时器事件中启动另一个视图模型。当我跳过这个计时器事件时,似乎启动器使用得很好。但是,如果启动是在活动期间完成的,则不会。有人可以看看问题出在哪里吗?
using System.Timers;
using Caliburn.Micro.Xamarin.Forms;
using MyProject.Resources;
using System.Windows.Input;
using Xamarin.Forms;
using System.Diagnostics;
namespace MyProject.ViewModels
{
public class PairingDeviceViewModel : BaseScreen {
public INavigationService NavigationService { get; set; }
private Timer timer;
private const float MAX = 20;
private string percentage;
private float rate;
public float Rate { get => rate; set => Set(ref rate, value); }
public string Percentage { get => percentage; set => Set(ref percentage, value); }
protected override void OnInitialize()
{
base.OnInitialize();
timer = new Timer
{
Interval = MAX,
};
}
protected override void OnActivate()
{
base.OnActivate();
timer.Elapsed += Timer_Elapsed;
timer.Start();
}
protected override void OnDeactivate(bool close)
{
base.OnDeactivate(close);
timer.Elapsed -= Timer_Elapsed;
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
Debug.WriteLine($"Timer_Elapsed");
Debug.WriteLine($"Rate {Rate}");
Rate++;
Percentage = string.Format(StringResources.PercentageNumber, Rate);
NotifyOfPropertyChange(() => Percentage);
if (Rate == MAX)
{
timer.Stop();
Debug.WriteLine($"navigation begins");
NavigationService.NavigateToViewModelAsync<ConfigurationListViewModel>();
}
Debug.WriteLine($"Timer_Elapsed END");
}
public ICommand SkipBluetoothScanning => new Command(() => {
timer.Stop();
NavigationService.NavigateToViewModelAsync<ConfigurationListViewModel>();
});
}
所以在我的 Timer_elapsed
方法中,一旦 Rate
等于 MAX
,我就会调用 NavigationService.NavigateToViewModelAsync<>..
。这个问题是这个条件 Rate==MAX
被调用了不止一次。
请查看日志文件。
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Timer_Elapsed
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Rate 0
Timer_Elapsed END
Timer_Elapsed
Rate 11
Timer_Elapsed END
Timer_Elapsed
Rate 12
Timer_Elapsed END
Timer_Elapsed
Rate 13
Timer_Elapsed END
Timer_Elapsed
Rate 14
Timer_Elapsed END
Timer_Elapsed
Rate 15
Timer_Elapsed END
Timer_Elapsed
Rate 16
Timer_Elapsed END
Timer_Elapsed
Timer_Elapsed END
Rate 17
Timer_Elapsed
Rate 18
Timer_Elapsed END
Timer_Elapsed
Rate 19
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
navigation begins
Timer_Elapsed END
[InputMethodManager] HSIFW - flag : 0 Pid : 6116
[InputMethodManager] HSIFW - flag : 0 Pid : 6116
Timer_Elapsed END
Timer_Elapsed END
Timer_Elapsed END
Timer_Elapsed END
Timer_Elapsed END
Timer_Elapsed END
[InputMethodManager] HSIFW - flag : 0 Pid : 6116
[InputMethodManager] HSIFW - flag : 0 Pid : 6116
Timer_Elapsed END
Timer_Elapsed END
[InputMethodManager] HSIFW - flag : 0 Pid : 6116
Timer_Elapsed END
Timer_Elapsed END
[InputMethodManager] HSIFW - flag : 0 Pid : 6116
Timer_Elapsed END
DispatcherTimer
是否是此功能或其他功能的更好解决方案?
非常感谢。
您可以像这样锁定线程以避免重复执行:
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
lock (this)
{
if (Math.Abs(Rate - MAX) < double.Epsilon){
//something you want to do
...
}
}
}