xamarin - 如果我运行每分钟运行一次并从 App.Xaml.cs OnStart() 调用的异步方法,是否存在任何可能的性能问题?
问题描述
我有这段代码,我的意图是当应用程序打开时,它将PointChecker.CheckPoints();
每分钟运行一个方法。
此方法与我的数据库同步运行更新db2.Execute("UPDATE ..... etc");
根据我的阅读理解:
https://xamarinhelp.com/xamarin-forms-async-task-startup/
有几种不同的方法可以实现这一点。
我想知道的是,运行这样的代码是否存在任何性能问题,如果我想以不同的方式运行它,这些问题可能会减少。特别是最近对 Xamarin.Forms 的工作方式(我的应用程序通过 Forms 在 iOS 和 Android 上运行)进行了任何更改,我应该考虑这些更改,这可能会导致执行此任务的更好方法。
public App() {
InitializeComponent();
DB.PopulateTables();
MainPage = new Japanese.MainPage();
}
protected override async void OnStart() {
await Task.Run(() => {
StartTimer();
});
}
public void StartTimer() {
if (!stopWatch.IsRunning)
stopWatch.Start();
Device.StartTimer(new TimeSpan(0, 0, 1), () => {
if (stopWatch.IsRunning && stopWatch.Elapsed.Minutes >= 1) {
PointChecker.CheckPoints();
stopWatch.Restart();
}
return true;
});
}
protected override void OnSleep() {
stopWatch.Reset(); base.OnSleep();
}
protected override void OnResume() {
base.OnResume(); stopWatch.Start();
}
解决方案
通过使用async void
,您删除了代码捕获和处理可能由调用计时器引发的任何异常的能力。所以避免async void
在除事件处理程序之外的任何东西上使用。
OnStart
然而不是事件处理程序。只是根据文档的常规方法...
应用程序开发人员覆盖此方法以在应用程序启动时执行操作。
作为一种解决方法,您可以创建自己的自定义事件和处理程序,以允许async void
在您的事件处理程序上执行。OnStart
当被应用程序调用时,您将订阅该事件,然后引发要异步处理的自定义事件。
StartTimer
不是一个繁重的方法,因此并不真正保证被异步调用。但是,它PointChecker.CheckPoints()
被声明为对您的数据库同步调用。
此方法与我的数据库同步运行更新
db2.Execute("UPDATE ..... etc");
然而,这可能会导致阻塞,这可能会在每次调用时影响性能。那应该是包含在异步调用中或重构为本机异步方法的方法。
//...
protected override void OnStart() {
PointsChecking += OnPointsChecking; //subscribe to event
StartTimer(); //start the timer as normal.
}
private event EventArgs PointsChecking = delegate { };
private async void OnPointsChecking(object sender, EventArgs args) {
//asynchronously check points without blocking main thread
await Task.Run(() => {
PointChecker.CheckPoints();
stopWatch.Restart();
});
}
public void StartTimer() {
if (!stopWatch.IsRunning)
stopWatch.Start();
Device.StartTimer(new TimeSpan(0, 0, 1), () => {
if (stopWatch.IsRunning && stopWatch.Elapsed.Minutes >= 1) {
PointsChecking(null, EventArgs.Empty); //invoked event
}
return true;
});
}
//...
计时器将负责引发事件以处理重复操作。通过使事件处理程序异步,您可以避免阻塞主线程,并具有额外的优势,即能够捕获和处理调用的数据库操作引发的任何异常(如果需要)。
推荐阅读
- xaml - XAML 链绑定不会自动更新
- python - 从python函数返回
- transactions - Plaid 交易中的商家是否有唯一标识符?
- recommender-systems - 电影剧情数据库
- angular - Angular 9 http拦截器获取Aws accesstoken
- node.js - Node.js - 为什么要读取未定义的属性“长度”?
- javascript - 我如何将我的旧密码与输入的旧密码进行比较,因为它们都默认由环回加密。用旧密码更改密码并进行比较
- javascript - 检查给定点是否在旋转元素的边界内
- javascript - 在子组件中进行一些渲染后数据变得不确定
- azure - Azure 表存储 - 501 未实现