踩雷,前端一直卡在获取token中
问题:一直卡在var token = SecureStorage.Default.GetAsync("auth_token").Result;public VideoService()
{
_httpClient = new HttpClient();
var token = SecureStorage.Default.GetAsync("auth_token");
} 这是一个典型的同步等候异步操作导致的死锁问题。在 VideoService 构造函数中使用 .Result 来同步等候异步操作是不保举的做法,这可能会导致死锁。
这个问题的根本缘故原由是:
[*] 在构造函数中使用 SecureStorage.Default.GetAsync("auth_token").Result 会同步阻塞当前线程,等候异步操作完成
[*] 而 SecureStorage 的异步操作可能必要在 UI 线程上完成某些操作
[*] 如果这个构造函数是在 UI 线程上调用的,就会造成死锁:UI 线程在等候异步操作完成,而异步操作又必要 UI 线程才气完成
办理方案是:
[*] 将同步的令牌获取操作改为真正的异步操作
[*] 在构造函数中只初始化 HttpClient 实例
[*] 添加一个私有的异步方法 InitializeHttpClient() 来处理令牌获取和设置 Authorization 头
[*] 使用 async void 模式(仅实用于这种初始化场景)来启动异步操作但不阻塞构造函数
如许修改后,构造函数会立刻返回,而令牌的获取和设置会在背景异步完成,避免了死锁问题。
必要注意的是,这种方法也有一个小缺点:如果用户立刻调用 VideoService 的方法,可能会在令牌设置完成之前就发出请求。不过在现实应用中,通常在登录后会有肯定的时间间隔再调用其他 API,以是这个问题不太可能发生。
如果您希望确保令牌肯定设置好再使用,可以思量以下两种方案:
[*] 将 VideoService 的构造函数也改为异步,并使用工厂模式创建实例
[*] 在每个公共方法中检查并确保令牌已设置
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}");
}
}
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]