C# 初始化Xamarin.Forms应用程序时找不到调用异步方法的方法
异步/等待线程在这里让我抓狂。我对异步初始化的可能性做了很多研究 问题就在这里。我正在尝试根据当前应用程序状态将我的应用程序加载到特定页面。以确定应用程序的状态。它包括扫描数据文件夹。为了在UWP中使用C# 初始化Xamarin.Forms应用程序时找不到调用异步方法的方法,c#,android,xamarin.forms,uwp,async-await,C#,Android,Xamarin.forms,Uwp,Async Await,异步/等待线程在这里让我抓狂。我对异步初始化的可能性做了很多研究 问题就在这里。我正在尝试根据当前应用程序状态将我的应用程序加载到特定页面。以确定应用程序的状态。它包括扫描数据文件夹。为了在UWP中使用存储API。我必须在Xamarin表单中创建一个async依赖项服务 我在这里使用一个带有AppManager类的单例模式 AppManager.cs public class AppManager{ public static AppManager Instance = new AppM
存储API
。我必须在Xamarin表单中创建一个async
依赖项服务
我在这里使用一个带有AppManager
类的单例模式
AppManager.cs
public class AppManager{
public static AppManager Instance = new AppManager();
public List<Jobs> JobList = new List<Jobs>();
public async Task InitializeAsync(){
JobList.AddRange(await DependencyService.Get<IFileService>().GetJobs());
}
public bool JobExists(string jobName){
return JobList.Any(j => j.Name == jobName);
}
}
由于初始化未完成,因此列表为空,因此我将始终转到PageB
。这是由于在synchronous
线程中运行async
代码造成的
我读过关于在中创建异步构造函数的多种方法。但是,它们仍然要求我在调用中执行wait
函数,这在本例中是不可能的
我还尝试将整个App()
构造函数代码移动到async Task
函数中,然后在构造函数中调用InitializeAsync().Wait()
。然而,Xamarin表单在运行时会抱怨。由于App
在MainPage
上有null
引用
我想知道是否有可能在不涉及不良实践(例如async void)的情况下使用等待的函数实现完全初始化?我还知道如何应对这种情况,例如使用
SystemIO
而不是Storage API
仍然适用于Xamarin Forms UWP。但我真的很想深入研究async
函数,而不仅仅是让它工作。谢谢。问题是Xamarin.Forms希望主页在初始化后立即设置。如果使用async
调用,则需要等待调用完成,这将不可避免地导致XF抱怨缺少页面
这个问题有三种解决方案
您可以在启动时显示临时“加载页面”。在这种情况下,您首先将MainPage
设置为通知用户应用正在加载的页面:
public App()
{
MainPage = new LoadingPage();
}
然后在OnStart
覆盖中继续执行async
操作:
protected override async void OnStart()
{
var appManager = AppManager.Instance;
await appManager.InitializeAsync();
if(appManager .JobExists("JobA"))
{
MainPage = new PageA();
}
else
{
MainPage = new PageB();
}
}
第二个选项是在初始化Xamarin.Forms之前连接异步初始化任务。对于UWP,您可以转到UWP项目的App.xaml.cs
文件,并将其放在Xamarin初始化之前的OnLaunched
方法覆盖中:
protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
...
var appManager = AppManager.Instance;
await appManager.InitializeAsync();
Xamarin.Forms.Forms.Init(e);
...
}
这只会延长基于UWP的启动屏幕,但在初始化Xamarin.Forms时,AppManager
将已经初始化
Adam Pedley在中描述了您的最终选择。它允许您在UI线程上运行任务,但会一直阻止,直到任务使用
这可能是最后一种选择,因为它可以被视为一种黑客行为,而不是一种合适的解决方案。将异步内容移动到应用程序生命周期事件之一而不是构造函数是合乎逻辑的。在构造函数中有这样的登录不是最佳实践。
protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
...
var appManager = AppManager.Instance;
await appManager.InitializeAsync();
Xamarin.Forms.Forms.Init(e);
...
}
Exrin.Common.ThreadHelper.Init(SynchronizationContext.Current);
Exrin.Common.ThreadHelper.RunOnUIThread(async () => { await MyMethod(); });