c# - 有没有办法避免需要受保护的覆盖 async void OnStart()
问题描述
我意识到 OnStart() 只是一个事件,所以我知道让它返回无效没有问题。但是我仍然收到恼人的消息给我一个警告
是否有替代方法允许我在 OnStart() 中运行异步方法?
我可以做一些事情,比如创建一个任务并让它们(或我当前在 OnStart 中的所有代码)在该任务中运行吗?或者我可以使用 _ = 构造来忽略在 OnStart 中运行的任务的输出吗?
更新:
根据 Nikosi 的建议,这是我想做的事情:
应用程序
public partial class App : Application
{
public async Task CheckLatestVersion()
{
try
{
var isLatest = await CrossLatestVersion.Current.IsUsingLatestVersion();
if (!isLatest)
{
var update = await MainPage.DisplayAlert("New Version", $"\nThere is a new version of this app available.\n\nWould you like to update now?\n", "Yes", "No");
if (update)
{
await CrossLatestVersion.Current.OpenAppInStore();
}
}
}
catch (Exception ex)
{
var ignore = ex;
}
}
private event EventHandler started = delegate { };
protected override void OnStart() {
this.started += onStarted; //Subscribe to event
started(this, EventArgs.Empty); //Raise event
}
protected async void onStarted(object sender, EventArgs args)
{
try
{
if (Connectivity.NetworkAccess == NetworkAccess.Internet)
{
if (Settings.Rev == REV.No && (new[] { 15, 30, 50 }).Contains(Settings.Trk2))
{
await ReviewAppAsync(Settings.Trk2);
}
if (App.devIsPhysical && (new[] { 10, 20, 30 }).Contains(Settings.Trk2))
{
await CheckLatestVersion();
}
// This
await Helper.PopulateMetrics();
// Or this
_ = Helper.PopulateMetrics();
await Helper.LogStart();
}
}
catch(Exception)
{
;
}
this.started -= onStarted; //Unsubscribe (OPTIONAL but advised)
}
}
帮手
public static async Task PopulateMetrics()
{
await Task.Run(() =>
{
if (App.CPUSpeed == 0)
{
var stopWatch = Stopwatch.StartNew();
stopWatch.Start();
ArrayList al = new ArrayList(); for (int i = 0; i < 5000000; i++) al.Add("hello");
App.CPUSpeed = 20000 / stopWatch.ElapsedMilliseconds;
}
});
}
public async Task ReviewAppAsync(int count)
{
try
{
async Task<bool> DelayAndDisplayAlert()
{
await Task.Delay(60000);
return await MainPage.DisplayAlert("Review", $"\nWe noticed that you've used this application {count} times. We'd love to get some feedback for the application.\n\nCan you help us by rating the application or leaving a review?\n", "Yes", "No");
}
if (count == 0 || await DelayAndDisplayAlert())
{
if (Plugin.StoreReview.CrossStoreReview.IsSupported)
{
if (Xamarin.Forms.Device.RuntimePlatform == "iOS")
Plugin.StoreReview.CrossStoreReview.Current.OpenStoreReviewPage("1477984412");
else if (Xamarin.Forms.Device.RuntimePlatform == "Android")
Plugin.StoreReview.CrossStoreReview.Current.OpenStoreReviewPage("com.ankiplus.Japanese");
}
}
}
catch (Exception ex)
{
Helper.RegisterCrash(ex,
new Dictionary<string, string> {
{"ReviewAppAsync", "Exception" },
{"Device Model", DeviceInfo.Model },
{"Exception", ex.ToString()}
});
}
}
解决方案
OnStart
实际上不是事件处理程序。这是对框架构建方式的误解。但是,您可以创建一个事件和异步处理程序,以允许您的异步代码按预期等待。
private event EventHandler started = delegate { };
protected override void OnStart() {
this.started += onStarted; //Subscribe to event
started(this, EventArgs.Empty); //Raise event
}
protected async void onStarted(object sender, EventArgs args) {
try {
//await custom code here
} catch {
//handle errors
}
//this.started -= onStarted; //Unsubscribe (OPTIONAL but advised)
}
异步事件处理程序async void
是允许并且可以正确处理的一种异常。
async void
与被覆盖的非事件处理程序一起使用OnStart
将导致遇到的任何异常都被吞没,因为async void
非事件处理程序是fire and forget。
推荐阅读
- python - 我被要求用 python 编写一个程序来检查排序算法是否稳定。需要一些帮助
- eloquent - Laravel 5.8 hasOneThrough 关系问题
- postgresql - 分区表的主键和约束
- c# - 属性数据未输出到控件
- python - 在 Python 中使用 Glob 打开嵌套文件夹中的文件
- python - 如何使用 Python request.get 从初始 URL 中找到重定向 URL?
- pdf - 如何缩放内容以使其适合itextpdf中的页面大小?
- python - 如何调用另一个文件的类中的函数?
- mysql - 从视图中按日期过滤不会返回所有记录
- python-3.x - 解压二进制文件内容;修改值;然后将内容打包到新的二进制文件中