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

异步执行未等待条件:获取AuthToken前提前执行代码求助

问题分析与解决方案

首先得揪出你代码里的核心问题——GetAuthToken()方法里的判断逻辑完全写反了,这直接导致它根本不会等待真实的AuthToken返回:

if (AuthToken != null || AuthToken != "") return AuthToken;

这个条件永远为true:如果AuthToken是null,AuthToken != ""会成立;如果是空字符串,AuthToken != null又会成立。所以第一次循环甚至第一次判断时,就直接返回了当前的空/null值,这就是为什么gameSocket会被提前初始化的原因!

接下来给你分步解决这个问题:

1. 先修复判断逻辑

把||改成&&,这样只有当AuthToken既不是null也不是空字符串时,才会返回有效Token:

if (AuthToken != null && AuthToken != "") return AuthToken;

2. 用更可靠的方式等待Token(替代轮询)

轮询Task.Delay是种比较低效的方式,推荐用TaskCompletionSource来监听Token的触发事件,这样事件一来就直接完成任务,不需要反复循环等待:

修改你的Client_Authenticate类:

private TaskCompletionSource<string> _authTokenTcs;

// 假设你有一个接收Token的事件(比如OnAuthTokenReceived),在收到服务器返回的Token时触发
private void OnAuthTokenReceived(string receivedToken)
{
    AuthToken = receivedToken;
    // 完成等待任务,把Token返回给调用方
    _authTokenTcs?.TrySetResult(receivedToken);
}

public Task<string> GetAuthToken()
{
    // 如果已经拿到Token了,直接返回
    if (!string.IsNullOrEmpty(AuthToken))
        return Task.FromResult(AuthToken);
    
    _authTokenTcs = new TaskCompletionSource<string>();
    
    // 设置超时:1.5秒后自动返回超时错误(对应你原来的15次*100ms)
    _ = Task.Delay(1500).ContinueWith(_ => 
        _authTokenTcs.TrySetResult("ERROR_TIMEOUT"), TaskContinuationOptions.OnlyOnRanToCompletion);
    
    return _authTokenTcs.Task;
}

这种方式会精准等待事件触发,没有不必要的延迟,也不会提前返回无效值。

3. 解决线程可见性问题

如果AuthToken是在Socket的IO线程(非主线程)中设置的,要确保主线程能看到最新的Token值,建议给AuthToken加上volatile修饰符:

private volatile string AuthToken;

4. 确认调用逻辑

最后要确保调用Init方法的地方,也是用await来等待完成的,比如:

// 调用方必须用await,否则会跳过等待直接执行后续代码
var initResult = await Init("你的服务器IP");
if (initResult == "SUCCESS")
{
    // 这里再执行需要gameSocket的逻辑
}

总结

最开始的判断逻辑错误是导致问题的元凶,换成TaskCompletionSource的方式能更优雅可靠地等待异步事件,再配合线程可见性的处理,就能确保拿到有效Token后才初始化gameSocket了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:22:14