如何从必须留在主线程上的方法统一调用异步方法

我有一个名为 的方法SendWithReplyAsync,它用于TaskCompletionSource在完成时发出信号并从服务器返回回复。


我正在尝试从服务器获取 2 个回复,该方法还需要更改场景、更改转换等,因此它需要在主线程上,正如我所理解的。


此方法绑定到OnClick()统一的 ui 按钮的 :


public async void RequestLogin()

{

    var username = usernameField.text;

    var password = passwordField.text;

    var message  = new LoginRequest() { Username = username, Password = password };


    var reply = await client.SendWithReplyAsync<LoginResponse>(message);


    if (reply.Result)

    {

        Debug.Log($"Login success!");

        await worldManager.RequestSpawn();

    }

    else Debug.Log($"Login failed! {reply.Error}");

}

如您所见,有一个调用 await WorldManager.RequestSpawn();


该方法如下所示:


public async Task RequestSpawn()

{

    //Get the initial spawn zone and transform

    var spawnReply = await client.SendWithReplyAsync<PlayerSpawnResponse>(new PlayerSpawnRequest());


    //Load the correct zone

    SceneManager.LoadScene("TestingGround");


    //Move the player to the correct location

    var state = spawnReply.initialState;

    player.transform.position = state.Position.Value.ToVector3();

    player.transform.rotation = Quaternion.Euler(0, state.Rotation.Value, 0);


    //The last step is to get the visible entities at our position and create them before closing the loading screen

    var statesReply = await client.SendWithReplyAsync<InitialEntityStatesReply>(new InitialEntityStatesRequest());


    SpawnNewEntities(statesReply);

}

因此,当我单击按钮时,我可以看到(服务器端)所有消息(登录请求、生成请求和初始实体状态请求)都在生成它。然而,没有任何事情发生在统一中。没有场景变化,(显然)没有位置或旋转更新。


我有一种感觉,当涉及到统一并且我的RequestSpawn方法没有在主线程上运行时,我对 async/await 不了解。


我尝试在所有方法上使用client.SendWithReplyAsync(...).Result和删除async关键字,但这只会导致死锁。我在 Stephen Cleary 的博客上阅读了更多关于死锁的信息(似乎他的网站消耗了 100% 的 CPU ......我是唯一一个吗?)


我真的不知道如何让这个工作。


慕码人8056858
浏览 154回答 2
2回答
打开App,查看更多内容
随时随地看视频慕课网APP