为什么在设置 MainPage 属性 之前等待 App.OnStart() 不加载主页
Why awaiting in App.OnStart() before setting the MainPage property doesn't load main page
首先,我知道文档指出我应该在 App
class 构造函数 (https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/application-class#mainpage-property) 中设置 MainPage
属性。
为了简化,我需要做的是在 OnStart() 事件处理程序中进行一些异步操作,然后设置 MainPage 属性。这个问题想触及框架本身的根本问题。
类似这样的东西(在一个空白的Xamarin.Forms项目上简化,如果你想试试):
public partial class App : Application
{
public App()
{
InitializeComponent();
...
}
protected override async void OnStart()
{
//Uncomenting the following line makes the page be shown
//MainPage = new Page() { BackgroundColor = Color.Red };
//Simulate some fast async work. If you comment this line the MainPage will be shown just fine
await Task.Delay(100);
//The page is never displayed to the user unless first commented line in this method is uncommented
MainPage = new Page(){ BackgroundColor = Color.Red };
}
}
如果您只是不等待任何事情并同步执行所有代码,则 MainPage 设置正确,但如果我等待任何任务则不会。为什么?
作为对原始 SynchronizationContext 的 await Task.Delay(100)
调用 returns(我假设将在 UI 线程上),我认为这不是问题所在。
非常感谢!
如您所见,OnStart
returns 无效,而不是 Task
,因此它不是异步的。你做到了 async void
但调用者(调用 OnStart 的框架代码)无法等待异步操作完成。对于调用者,OnStart
在 await Task.Delay
命中时(即 OnStart
returns 时)立即完成,因此它会继续执行其他操作。当 await Task.Delay
完成并且您设置 MainPage
- 您实际上并未处于初始化过程的 OnStart
阶段,该阶段已经在 100 毫秒前完成。
考虑这个应该澄清它的例子:
public class Program
{
public static void Main()
{
var app = new Application();
app.Start();
}
}
class Application
{
public string MainPage { get; set; }
protected virtual void OnStart()
{
}
public void Start()
{
Console.WriteLine("calling OnStart");
// can't await or anything here, it returns void
OnStart();
Console.WriteLine("OnStart called");
// now we consider initialization is done and check MainPage
if (MainPage != null)
{
Console.WriteLine(MainPage);
}
Console.WriteLine("Initialization done");
}
}
class MyApplication : Application
{
protected override async void OnStart()
{
await Task.Delay(100);
// we set MainPage but it's too late
MainPage = "Hello";
}
}
首先,我知道文档指出我应该在 App
class 构造函数 (https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/application-class#mainpage-property) 中设置 MainPage
属性。
为了简化,我需要做的是在 OnStart() 事件处理程序中进行一些异步操作,然后设置 MainPage 属性。这个问题想触及框架本身的根本问题。
类似这样的东西(在一个空白的Xamarin.Forms项目上简化,如果你想试试):
public partial class App : Application
{
public App()
{
InitializeComponent();
...
}
protected override async void OnStart()
{
//Uncomenting the following line makes the page be shown
//MainPage = new Page() { BackgroundColor = Color.Red };
//Simulate some fast async work. If you comment this line the MainPage will be shown just fine
await Task.Delay(100);
//The page is never displayed to the user unless first commented line in this method is uncommented
MainPage = new Page(){ BackgroundColor = Color.Red };
}
}
如果您只是不等待任何事情并同步执行所有代码,则 MainPage 设置正确,但如果我等待任何任务则不会。为什么?
作为对原始 SynchronizationContext 的 await Task.Delay(100)
调用 returns(我假设将在 UI 线程上),我认为这不是问题所在。
非常感谢!
如您所见,OnStart
returns 无效,而不是 Task
,因此它不是异步的。你做到了 async void
但调用者(调用 OnStart 的框架代码)无法等待异步操作完成。对于调用者,OnStart
在 await Task.Delay
命中时(即 OnStart
returns 时)立即完成,因此它会继续执行其他操作。当 await Task.Delay
完成并且您设置 MainPage
- 您实际上并未处于初始化过程的 OnStart
阶段,该阶段已经在 100 毫秒前完成。
考虑这个应该澄清它的例子:
public class Program
{
public static void Main()
{
var app = new Application();
app.Start();
}
}
class Application
{
public string MainPage { get; set; }
protected virtual void OnStart()
{
}
public void Start()
{
Console.WriteLine("calling OnStart");
// can't await or anything here, it returns void
OnStart();
Console.WriteLine("OnStart called");
// now we consider initialization is done and check MainPage
if (MainPage != null)
{
Console.WriteLine(MainPage);
}
Console.WriteLine("Initialization done");
}
}
class MyApplication : Application
{
protected override async void OnStart()
{
await Task.Delay(100);
// we set MainPage but it's too late
MainPage = "Hello";
}
}