为何从SplashScreen到MainPage的导航顺序出现异常?
问题分析与解决方案
嘿,我帮你揪出问题所在了!你的代码里有两个关键问题导致了顺序错乱和页面丢失:
核心问题1:同步阻塞的“伪异步”方法
你写的Test方法虽然标记了async Task,但里面用的是同步while循环实现延迟——这根本不是真正的异步操作!它会直接阻塞UI线程,导致整个程序卡在这5秒里,连构造函数都没法正常走完。
核心问题2:构造函数里直接调用async void方法
在ExtendedSplash的构造函数里直接调用LoadDataAsync(async void类型),加上上面的同步阻塞,就出现了诡异的执行顺序:
- 调用
new ExtendedSplash(...)时,构造函数开始执行 LoadDataAsync被调用,进入Test方法阻塞5秒- 5秒后,
LoadDataAsync直接把Window.Current.Content设为rootFrame(这时候构造函数还没执行完!) - 构造函数终于执行完,回到
App类的代码,把Window.Current.Content设为extendedSplash,直接覆盖了刚设置的rootFrame
结果就是你看到的:先卡5秒显示初始Logo,然后显示ExtendedSplash,MainPage被彻底覆盖消失。
修复方案
第一步:把同步延迟改成真正的异步
替换你的Test方法,用Task.Delay实现非阻塞的异步延迟,这样不会卡住UI线程:
private async Task Test() { await Task.Delay(5000); // 真正的异步延迟,释放UI线程让启动页正常显示 }
第二步:把异步加载移到构造函数完成后执行
不要在构造函数里直接调用async void方法,而是订阅Loaded事件,确保ExtendedSplash已经被设置为窗口内容后,再开始加载数据:
修改ExtendedSplash的构造函数和添加事件处理:
public ExtendedSplash(IActivatedEventArgs e, bool loadState) { this.InitializeComponent(); Window.Current.SizeChanged += ExtendedSplash_OnResize; this.splashScreen = e.SplashScreen; this.activatedEventArgs = e; OnResize(); rootFrame = new Frame(); // 订阅Loaded事件,等页面加载完成后再执行异步操作 this.Loaded += ExtendedSplash_Loaded; } // 异步加载数据的事件处理程序 private async void ExtendedSplash_Loaded(object sender, RoutedEventArgs e) { await LoadDataAsync(activatedEventArgs); } private async Task LoadDataAsync(IActivatedEventArgs e) { await Test(); rootFrame.Navigate(typeof(MainPage)); Window.Current.Content = rootFrame; Window.Current.Activate(); }
额外说明
async void方法只应该用于事件处理程序,在构造函数里调用会导致不可预测的线程问题- 修改后流程会变成:
App设置ExtendedSplash为窗口内容并激活显示 → 启动页加载完成后开始异步等待5秒 → 延迟结束后切换到MainPage,完全符合预期
内容的提问来源于stack exchange,提问作者Viewed
相关产品推荐
相关产品推荐

