You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinUI3主窗口加载时显示启动窗口的实现难题

问题解决:WinUI3 启动窗口显示空白并阻塞的处理方案

核心问题分析

你的代码中GetMode()是同步执行的耗时操作,直接阻塞了UI线程——WinUI3的UI渲染依赖UI线程的响应,这就导致StartupWindow的渲染被推迟到GetMode()执行完毕后,最终出现"空白闪一下就关闭"的现象。此外,后台线程中直接获取DispatcherQueue会返回null,是因为该对象只能在UI线程上下文获取。

解决方案步骤

  1. 将耗时操作异步执行,避免阻塞UI线程
  2. 让UI线程优先完成启动窗口的渲染
  3. 提前在UI线程获取DispatcherQueue,供后台线程的UI更新操作使用

修改后的代码示例

App.xaml.cs中的OnLaunched方法

private Window _mainWindow;
protected override async void OnLaunched(LaunchActivatedEventArgs args)
{
    var startupWindow = new StartupWindow();
    startupWindow.Activate();

    // 让UI线程优先处理启动窗口的渲染任务,确保窗口能正常显示
    await Task.DispatcherYield();

    // 提前在UI线程获取DispatcherQueue,后续后台线程可通过它调度UI更新
    var uiDispatcher = DispatcherQueue.GetForCurrentThread();

    // 异步执行耗时操作,避免阻塞UI线程
    await Task.Run(() =>
    {
        GetMode();
        
        // 如果GetMode中需要更新UI,必须通过提前获取的DispatcherQueue调度
        // uiDispatcher.TryEnqueue(() => 
        // {
        //     // 这里写UI更新逻辑,比如更新启动窗口的提示文本
        // });
    });

    startupWindow.Close();
    _mainWindow.Activate();
}

StartupWindow的XAML示例(确保有可显示的内容)

<Window
    x:Class="YourAppNamespace.StartupWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="320" Height="180"
    WindowStyle="None"
    IsTabStop="False">
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
            <ProgressRing IsActive="True" Width="48" Height="48" Margin="0 0 0 12"/>
            <TextBlock Text="正在加载资源..." FontSize="14"/>
        </StackPanel>
    </Grid>
</Window>

关键细节说明

  • async void在OnLaunched中是合法的,因为这是框架提供的入口方法,无需担心异步回调问题。
  • Task.DispatcherYield()会让UI线程先处理当前队列中的渲染消息,确保StartupWindow能完整显示后再执行耗时操作。
  • 主窗口监听系统事件时,要在UI线程(比如主窗口构造函数)中提前获取DispatcherQueue并保存为字段,后续在事件回调中直接使用该字段调度UI更新,避免后台线程获取null的问题。
  • 如果GetMode()本身可以重构为异步方法(比如包含IO操作),直接使用await GetModeAsync()会比Task.Run()更高效,无需额外线程调度。

内容的提问来源于stack exchange,提问作者Hector Lazarin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 16:20:01