首先,我知道文档指出我应该在 App
类构造函数 ( https://learn.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 设置正确,但如果我等待任何任务则不会。为什么?
由于 await Task.Delay(100)
调用返回到原始 SynchronizationContext(我假设将在 UI 线程上),我认为这不是问题所在。
非常感谢!
最佳答案
如您所见,OnStart
返回 void,而不是 Task
,因此它不是异步的。您将其设为 async void
但调用方(调用 OnStart 的框架代码)无法等待该异步操作完成。对于调用方,OnStart
在 await Task.Delay
命中时完成(即 OnStart
返回),因此它会继续执行其他操作。当 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";
}
}
关于c# - 为什么在设置 MainPage 属性之前在 App.OnStart() 中等待不加载主页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69943109/