当前位置: 首页 > news >正文

踩雷,前端一直卡在获取token中

问题:一直卡在var token = SecureStorage.Default.GetAsync("auth_token").Result;

 public VideoService()
 {
     _httpClient = new HttpClient();
     var token = SecureStorage.Default.GetAsync("auth_token");
 }

这是一个典型的同步等待异步操作导致的死锁问题。在 VideoService 构造函数中使用 .Result 来同步等待异步操作是不推荐的做法,这可能会导致死锁。

这个问题的根本原因是:

  1. 在构造函数中使用 SecureStorage.Default.GetAsync("auth_token").Result 会同步阻塞当前线程,等待异步操作完成

  2. 而 SecureStorage 的异步操作可能需要在 UI 线程上完成某些操作

  3. 如果这个构造函数是在 UI 线程上调用的,就会造成死锁:UI 线程在等待异步操作完成,而异步操作又需要 UI 线程才能完成

解决方案是:

  1. 将同步的令牌获取操作改为真正的异步操作

  2. 在构造函数中只初始化 HttpClient 实例

  3. 添加一个私有的异步方法 InitializeHttpClient() 来处理令牌获取和设置 Authorization 头

  4. 使用 async void 模式(仅适用于这种初始化场景)来启动异步操作但不阻塞构造函数

这样修改后,构造函数会立即返回,而令牌的获取和设置会在后台异步完成,避免了死锁问题。

需要注意的是,这种方法也有一个小缺点:如果用户立即调用 VideoService 的方法,可能会在令牌设置完成之前就发出请求。不过在实际应用中,通常在登录后会有一定的时间间隔再调用其他 API,所以这个问题不太可能发生。

如果您希望确保令牌一定设置好再使用,可以考虑以下两种方案:

  1. 将 VideoService 的构造函数也改为异步,并使用工厂模式创建实例

  2. 在每个公共方法中检查并确保令牌已设置

public VideoService()
{
    _httpClient = new HttpClient();
    InitializeHttpClient();
}

private async void InitializeHttpClient()
{
    try
    {
        // 从安全存储中获取认证令牌
        var token = await SecureStorage.Default.GetAsync("auth_token");
        if (!string.IsNullOrEmpty(token))
        {
            _httpClient.DefaultRequestHeaders.Authorization = 
                new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);
        }
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine($"初始化 HttpClient 时出错: {ex.Message}");
    }
}

http://www.dtcms.com/a/123065.html

相关文章:

  • GaussDB存储过程深度解析:从开发到生产实践
  • 4.9-4.10学习总结 Stream流练习+方法引用+异常
  • C/C++内存管理:从基础到进阶
  • Leetcode 69——不使用sqrt函数情况下求平方根整数部分(暴力求解法和二分查找法)
  • Pytest多环境切换实战:测试框架配置的最佳实践!
  • EPGAN:融合高效注意力的生成对抗网络图像修复算法
  • Promise(微任务)和setTimeout(宏任务)的理解
  • P1825 [USACO11OPEN] Corn Maze S【java】【AC代码】
  • C++:函数模板类模板
  • 什么是巨型帧Jumbo Frames?云服务器开启巨型帧有什么用?
  • 2025年4月9日-华为暑期实习-第二题-200分
  • 动态类生成 / 加载机制(更新)
  • Java集合框架:核心接口与关系全解析
  • springboot中测试python脚本:ProcessBuilder
  • 如何使用 PyTorch 和 EfficientNet 创建一个 AI 游戏外挂[特殊字符]
  • 基于MCP协议调用的大模型agent开发03
  • InnoDB 事务更新过程深度剖析:原理、流程与优化
  • 前端-vue2核心
  • 如何用postman做接口自动化测试?
  • Seata框架,如何保证事务的隔离性?
  • 【时时三省】(C语言基础)用switch语句实现多分支选择结构
  • 【运维 | 硬件】服务器中常见的存储插槽类型、对应的传输协议及其特性总结
  • 环信鸿蒙版 UIKit 快速上手指南
  • 如何将多个Word文档合并
  • 【HTML】动态背景效果前端页面
  • 基于 Qt4 的图片处理工具开发(二):增加对比度调节、界面布局优化、多线程操作
  • 初识Redis · 简单理解Redis
  • 使用注解@RequestBody变红的解决问题
  • 【spark认任务提交】配置优先级顺序
  • 银河麒麟v10(arm架构)部署Embedding模型bge-m3【简单版本】