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

.NET Maui异步函数未执行完成的原因分析求助

问题分析与解决方案

核心问题1:异步操作同步等待引发死锁

你的代码中调用GoogleWebAuthorizationBroker.AuthorizeAsync(...).Result,这是用同步方式阻塞异步方法的错误写法。在.NET Maui的UI线程环境下,这种操作会触发死锁:

  • UI线程被.Result阻塞,等待异步方法返回结果
  • AuthorizeAsync内部需要UI线程完成授权流程(比如弹出登录窗口),但UI线程已被占用,无法继续执行
    最终表现为程序卡在该步骤,看起来像是方法直接终止。

核心问题2:文件路径错误

string PathToCredentials = @"\credentials.json"使用了根路径,在.NET Maui中这个路径并不指向应用的资源目录,会导致FileStream无法找到文件,抛出未捕获的异常,直接终止Initialize方法。

修复后的代码

public partial class MainPageViewModel: ObservableObject
{
    public ObservableCollection<Models.File> DriveFileInfo { get; set; }

    public MainPageViewModel()
    {
        DriveFileInfo = new ObservableCollection<Models.File>();
    }

    [RelayCommand]
    private async Task Populate()
    {
        try
        {
            await Initialize();
        }
        catch (Exception ex)
        {
            // 添加异常处理,便于调试问题
            Debug.WriteLine($"初始化失败: {ex.Message}");
        }
    }

    private async Task Initialize()
    {
        // 修正凭证文件路径:使用MAUI提供的应用数据目录
        string credentialsPath = Path.Combine(FileSystem.AppDataDirectory, "credentials.json");
        // 指定合法的存储路径给FileDataStore
        var tokenStorage = new FileDataStore(FileSystem.AppDataDirectory, true);

        UserCredential credential;
        await using (var stream = new FileStream(credentialsPath, FileMode.Open, FileAccess.Read))
        {
            // 替换.Result为await,避免死锁
            credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.FromStream(stream).Secrets,
                    new[] { DriveService.ScopeConstants.DriveReadonly },
                    "userName",
                    CancellationToken.None,
                    tokenStorage);
        }

        // 创建Drive服务实例
        var service = new DriveService(new BaseClientService.Initializer()
        {
            HttpClientInitializer = credential
        });

        var request = service.Files.List();
        request.PageSize = 1000;
        request.Q = "parents in '1bbZTzmYtlxFTA06JJvAE-tojIAoOHETM'";
        var results = await request.ExecuteAsync();

        // 清空原有集合而非重新实例化,避免UI绑定失效
        DriveFileInfo.Clear();
        foreach (var driveFile in results.Files)
        {
            DriveFileInfo.Add(new Models.File(driveFile.Name,
                driveFile.MimeType, driveFile.Id));
        }
    }
}

额外注意事项

  • 异常处理:添加try-catch块可以捕获文件找不到、授权失败等错误,方便定位问题。
  • UI绑定更新:直接重新实例化DriveFileInfo会导致原有UI绑定失效,改用Clear()后添加新元素更合理。
  • 权限与路径:使用FileSystem.AppDataDirectory确保MAUI应用对文件有合法的读写权限。

内容的提问来源于stack exchange,提问作者Joao Lima

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 13:18:09