c# - 当我更改页面以及将我的应用程序移至后台时,如何停止 Device.StartTimer ()?并正确使用 MessagingCenter
问题描述
我正在尝试创建一个 ListView,它每 5 秒刷新一次其内容,为此我使用的是 Device.StartTimer (),我设法让它工作,但我注意到 Device.StartTimer () 是对应用程序来说是全局的,即使我更改页面或更改设备上的应用程序,回调中的内容仍在运行。
我的问题是:当我更改页面和更改应用程序时,如何让计时器停止?
到目前为止,我已经取得了一些进展,即使用 OnAppearing、OnDisAppearing 和 MessagingCenter,我已经设法在计时器停止时更改页面。
有了这个实现,我担心我真的不知道我是否真的退订了消息,这是正确的地方,我也希望有人告诉我。
下面是我的视图和视图模型的片段:
看法:
public partial class MonitoringView : TabbedPage
{
MonitoringViewModel context = new MonitoringViewModel();
public MonitoringView()
{
InitializeComponent();
BindingContext = context;
}
protected override void OnAppearing()
{
base.OnAppearing();
MessagingCenter.Send<MonitoringView>(this, "OnAppearing");
}
protected override void OnDisappearing()
{
base.OnDisappearing();
MessagingCenter.Send<MonitoringView>(this, "OnDisAppearing");
}
}
视图模型:
public class MonitoringTabsViewModel : Notificable
{
public string IdCode { get; set; }
public bool InPage { get; set; }
private string description;
public string Description
{
get { return description; }
set
{
description = value;
OnPropertyChanged();
}
}
private ObservableCollection<PcData> sensors;
public ObservableCollection<PcData> Sensors
{
get { return sensors; }
set
{
sensors = value;
OnPropertyChanged();
}
}
public MonitoringTabsViewModel(string idCode, string description)
{
IdCode = idCode;
Description = description;
LoadSensors(idCode);
MessagingCenter.Subscribe<MonitoringView>(this, "OnAppearing", (sender) =>
{
InPage = true;
});
MessagingCenter.Subscribe<MonitoringView>(this, "OnDisAppearing", (sender) =>
{
InPage = false;
});
Device.StartTimer(TimeSpan.FromSeconds(5), TimerCallBack);
}
private bool TimerCallBack()
{
if (InPage)
{
RefreshSensors(IdCode);
MessagingCenter.Unsubscribe<MonitoringView>(this, "OnAppearing");
return true;
}
else
{
MessagingCenter.Unsubscribe<MonitoringView>(this, "OnDisAppearing");
return false;
}
}
private async void LoadSensors(string idCode)
{
Sensors = new ObservableCollection<PcData>(await App.WebApiManager.GetCurrentStatusDeviceAsync(idCode));
}
private async void RefreshSensors(string idCode)
{
Sensors = null;
Sensors = new ObservableCollection<PcData>(await App.WebApiManager.GetCurrentStatusDeviceAsync(idCode));
}
}
解决方案
解决方案:
有了这个实现,我担心我真的不知道我是否真的退订了消息
为了测试您是否真的取消订阅了该消息,您可以在调试与 VS 连接的应用程序时breakpoint
在该RefreshSensors
函数中添加一个。
MessagingCenter.Send<MonitoringView>(this, "OnAppearing");
然后你可以在你离开后像在另一个页面一样发送消息MonitoringView
,看看是否breakpoint
已经触发,如果没有,则表示你已经成功取消订阅消息。
在你的代码中TimerCallBack
,我认为你should not
在这里取消订阅消息。当您从另一个页面返回时,您将永远不会收到该消息,因为您已取消订阅它们。当此页面为 时,您可以取消订阅该消息onDestory
。
private bool TimerCallBack()
{
if (InPage)
{
RefreshSensors(IdCode);
//MessagingCenter.Unsubscribe<MonitoringView>(this, "OnAppearing");
return true;
}
else
{
//MessagingCenter.Unsubscribe<MonitoringView>(this, "OnDisAppearing");
return false;
}
}
另外,您应该输入Device.StartTimer(TimeSpan.FromSeconds(5), TimerCallBack);
内部onappearing
消息。
public MonitoringTabsViewModel(string idCode, string description)
{
IdCode = idCode;
Description = description;
LoadSensors(idCode);
MessagingCenter.Subscribe<MonitoringView>(this, "OnAppearing", (sender) =>
{
InPage = true;
Device.StartTimer(TimeSpan.FromSeconds(5), TimerCallBack);
});
MessagingCenter.Subscribe<MonitoringView>(this, "OnDisAppearing", (sender) =>
{
InPage = false;
});
}
收到OnAppearing
消息后,Device.StartTimer
将在页面中运行,一旦OnDisAppearing
收到消息,回调将返回 false 并Device.StartTimer
停止。
推荐阅读
- sql - 过程中的 DBMS_UTILITY.COMPILE_SCHEMA
- c++ - 为什么 switch 和 if 语句与转换运算符的行为不同?
- apache-spark - 自定义 /src/main/resources/log4j.properties 未在 Spark 2.2 中加载
- javascript - Js:解析 .mov 元数据
- c# - 防止在逗号分隔的字符串中替换已替换的字符串
- android - FusedLocationProviderClient api异常,同时申请位置更新坐标
- emacs - Emacs 单引号字符串中的通用模式被突出显示
- angular - .NET Core 2/Angular 5 图像压缩
- php - 我想在 Prestashop 中通过 id 获取产品,并列出它们
- ios - 呈现的 UIViewController 在 segue 动画后消失