异步执行未等待条件:获取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
相关产品推荐
相关产品推荐

