Xamarin 计时器崩溃

Posted

技术标签:

【中文标题】Xamarin 计时器崩溃【英文标题】:Xamarin Timer crashes 【发布时间】:2022-01-06 03:20:00 【问题描述】:

所以我已经在代码中完成了这个:

public partial class Timer : ContentView , INotifyPropertyChanged
    
        private int seconds = 30;
        
        private System.Timers.Timer timer;
        public Timer()
        
            InitializeComponent();
            timer = new System.Timers.Timer();
            timer.Interval = 1000;
            timer.AutoReset = true;
            timer.Elapsed += new System.Timers.ElapsedEventHandler(OneSecondPassed);
            timer.Enabled = true;
        
        private void OneSecondPassed(object source, System.Timers.ElapsedEventArgs e)
        
            seconds--;
            Time = seconds.ToString();
        
        public event PropertyChangedEventHandler PropertyChanged;
        public string Time
        
            get => seconds.ToString();
            set
            
                Time = value;
                if (PropertyChanged != null)
                
                    PropertyChanged(this ,  new PropertyChangedEventArgs("Time"));
                
                
               
        
    

然后在 XAML 中将我的标签文本绑定到它:

 <Label  BindingContext ="x:Reference this"
              Text="Binding Time"/>

当我启动应用程序时,它崩溃了......我真的不明白 PropertyChanged 是如何工作的,只是 INotifyPropertyChanged 实现了它。另外,当我声明 PropertyChanged 时,它告诉我 BindableObject.PropertyChanged 已经存在,使用 new in为了隐藏它。如果您能解释界面及其事件的工作原理,我将非常感谢。

【问题讨论】:

什么是异常/错误消息? 您可能需要使用Dispatcher 更改Text 属性的值,否则绑定在错误的线程上运行,也许是ThreadPool? Timer documentation。可以通过将 Timer 的 SynchronizingObject 设置为 this 来缓解? 【参考方案1】:

你的 setter 正在创建一个无限循环。

set

   // this will call the setter again, infinitely
   Time = value;
   ...

你已经有一个 seconds 的私有变量,你应该在这里使用它

public int Time
    
        get => seconds;
        set
        
            seconds = value;
            if (PropertyChanged != null)
            
                PropertyChanged(this ,  new PropertyChangedEventArgs("Time"));
            
            
           
    

private void OneSecondPassed(object source, System.Timers.ElapsedEventArgs e)

   Time--;

【讨论】:

我希望 Time 属性为字符串类型,这样我就可以将标签的文本绑定到它...所以我不能真正做 Time--; 当然可以。您可以将 int 绑定到标签 - .NET 会自动为您转换它。 标签仍然保持不变...有什么想法吗? 我只想说 label.text = seconds--.ToString() 每秒而不是使用绑定.. 只要 UI 线程上发生更新,绑定就应该可以工作【参考方案2】:

当我声明 PropertyChanged 时,它告诉我 BindableObject.PropertyChanged 已经存在

我看到Timer 继承自ContentView

ContentView 是一个BindableObject,因此它已经实现了绑定中使用的所有内容,例如 PropertyChanged。删除PropertyChanged的声明。


可选:您也可以删除 , INotifyPropertyChanged - ContentView 会为您执行此操作。不过放在那里也无害。

【讨论】:

哦,很高兴知道!这很令人困惑

以上是关于Xamarin 计时器崩溃的主要内容,如果未能解决你的问题,请参考以下文章

在 Xamarin 轮播页面中放置一个计时器

将计时器添加到Xamarin应用程序(c#)

Xamarin.Forms 中的计时器

Xamarin.Android RunOnUIThread 和 onTimedEvent 延迟/滞后(我正在尝试显示倒数计时器)

C# Xamarin - 如何延迟第二个 void

API 计时器启动 Workbook.close 时 Excel 2016 崩溃