调度异步方法执行

问题描述 投票:0回答:1

我有一款游戏可以计算玩家在远程系统上的操作。为了争论起见,假设这个系统一次只能处理一个动作,但玩家应该能够根据需要排列任意数量的动作。

每当玩家执行动作时,客户端向远程发送请求:

async void ActionAsync(){

string id = await ActionRequestToRemote();
CharacterActions.Add(new CharacterAction(id, currentlySelectedGameobject));      
}

获取 id 足够快,但之后需要远程大约 6 秒才能返回新的游戏状态,在此期间所有进一步的等待请求都会被遗忘(例如,玩家在一秒钟内点击 3 次)。

让玩家保持排队动作的最佳方式是什么,同时拖延/安排

await ActionARequestToRemote(id)
的执行直到前一个动作完成?

每当远程处理完成时,调用以下方法开始播放动画等

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;
            }
        }
    }

我目前通过列表递归地使自己出队,在玩家点击时忽略请求,并在所有任务执行完成后重新发送它们。但这似乎不够优雅,而且可能有更好的方法?

c# unity3d asynchronous scheduled-tasks
1个回答
0
投票

在我看来你想使用某种

ConcurrentQueue
并允许动作堆积在那里。

像例如

public readonly struct ActionResult
{
    public string Type { get; }
    public bool Success { get; }

    public ActionResult(string type, bool success)
    {
        Type = type;
        Success = success;
    }
}

private readonly ConcurrentQueue<CharacterAction> CharacterActions = new ();
private bool isHandlingQueuedActions;

public event Action<ActionResult> onActionResult;

public void SendActionQueued(CharacterAction action)
{
    CharacterActions.Enqueue(action);

    if(!isHandlingQueuedActions)
    {
        Task.Run(async ()=> await HandleQueuedActions());
    }
}

private async Task HandleQueuedActions()
{
    isHandlingQueuedActions = true;

    while(CharacterActions.TryDequeue(out var action)) 
    {
        ActionResult result = await HoweverYouSubmitTheAction(action);
        onActionResult?.Invoke(result);
    }

    isHandlingQueuedActions = false;
}
© www.soinside.com 2019 - 2024. All rights reserved.