在计时器内启动Viewmodel已失效

时间:2019-05-29 14:38:27

标签: c# visual-studio xamarin xamarin.forms caliburn.micro

我正在尝试在计时器事件中启动另一个视图模型。当我跳过此计时器事件时,似乎启动器被很好地使用了。但是,如果启动是在事件内完成的,则不会。有人可以看看问题出在哪里吗?

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方法中,一旦NavigationService.NavigateToViewModelAsync<>..等于Rate,我就叫MAX。这个问题是,这个条件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是此功能或其他功能的更好解决方案吗?

非常感谢。

1 个答案:

答案 0 :(得分:0)

您可以锁定线程以避免像这样重复执行:

private void Timer_Elapsed(object sender, ElapsedEventArgs e)
  {
     lock (this)
        {
         ...
        }
  }