异步方法执行调度:游戏远程动作队列处理方案咨询
最优动作串行调度实现方案
核心思路是通过线程安全队列缓存玩家动作+异步任务串行链,确保远程系统同一时间仅处理一个动作,同时不丢失玩家的任何操作请求,替代递归遍历的方案:
实现步骤与代码
1. 新增核心字段
在客户端逻辑类中添加以下字段,用于维护动作队列、跟踪执行状态和同步远程回调:
// 线程安全的待处理动作队列,存储玩家选中的游戏对象 private readonly ConcurrentQueue<GameObject> _pendingActions = new ConcurrentQueue<GameObject>(); // 跟踪当前正在执行的异步任务链,避免重复调度 private Task _currentExecutionTask = Task.CompletedTask; // 同步远程处理完成的信号量,确保动作按顺序执行 private readonly SemaphoreSlim _actionCompletedSignal = new SemaphoreSlim(0, 1);
2. 修改玩家动作触发逻辑
玩家点击时不再直接发起远程请求,而是将动作加入队列并启动调度:
// 玩家点击动作按钮时调用此方法 void OnPlayerActionClicked() { _pendingActions.Enqueue(currentlySelectedGameobject); // 启动队列处理,用_=忽略返回任务避免警告 _ = ProcessActionQueueAsync(); }
3. 实现串行队列处理逻辑
这个方法会循环处理队列中的动作,确保前一个动作的完整流程(发送请求→远程处理→本地更新)完成后,再处理下一个:
private async Task ProcessActionQueueAsync() { // 用原子操作确保只有一个线程在处理队列,防止重复调度 if (Interlocked.CompareExchange(ref _currentExecutionTask, Task.CompletedTask, Task.CompletedTask) != Task.CompletedTask) return; try { while (_pendingActions.TryDequeue(out var selectedObj)) { try { // 发送远程请求获取动作ID string actionId = await ActionRequestToRemote(); // 将动作加入本地列表 CharacterActions.Add(new CharacterAction(actionId, selectedObj)); // 等待远程处理完成(即UpdateLocalGameState被调用) await _actionCompletedSignal.WaitAsync(); // 移除已完成的动作(对应UpdateLocalGameState中取第一个元素的逻辑) if (CharacterActions.Count > 0) CharacterActions.RemoveAt(0); } catch (Exception ex) { // 处理请求失败场景:记录日志、提示玩家,避免队列阻塞 Debug.LogError($"动作处理失败: {ex.Message}"); if (CharacterActions.Count > 0) CharacterActions.RemoveAt(0); } } } finally { // 重置任务状态,允许下次调度 Interlocked.Exchange(ref _currentExecutionTask, Task.CompletedTask); } }
4. 修改本地状态更新方法
在远程回调完成后释放信号量,通知队列可以处理下一个动作:
void UpdateLocalGameState(string type, bool success) { if (success) { switch (type) { case "ActionA": LocallyDoActionA(CharacterActions[0]); break; case "ActionB": LocallyDoActionB(CharacterActions[0]); break; case "ActionC": LocallyDoActionC(CharacterActions[0]); break; } } // 释放信号量,允许队列处理下一个动作 _actionCompletedSignal.Release(); }
方案优势
- 无递归逻辑,代码结构清晰易维护
- 线程安全队列确保玩家快速点击的动作不会丢失
- 用信号量精准同步远程处理流程,保证动作严格按顺序执行
- 异常处理逻辑避免单个动作失败导致整个队列阻塞
内容的提问来源于stack exchange,提问作者z3po
相关产品推荐
相关产品推荐

