我有一個名為 的方法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
2021-10-23 16:31:47