Unity 引擎在访问任务 <Token> 时冻结。结果

Unity Engine freezes when Accessing Task<Token>.Result

我已经实现了一些代码来访问受保护的 oauth 2.0 api。我一点击“播放”按钮,Unity 引擎就冻结了。我必须通过任务管理器关闭它。

我的代码:

public class importFromAPI : MonoBehaviour
{
    // Start is called before the first frame update
    void Start()
    {
        HttpClient client = new HttpClient();
        Task<Token> task = GetElibilityToken(client);
        //Token token = task.Result;
    }

    // Update is called once per frame
    void Update()
    {

    }


    // OAuth Stuff




private static async Task<Token> GetElibilityToken(HttpClient client)
{
    string baseAddress = @"*REDACTED*/oauth/token";

    string grant_type = "client_credentials";
    string client_id = "*REDACTED*";
    string client_secret = "*REDACTED*";
    string audience = "*REDACTED*";

    var form = new Dictionary<string, string>
        {
            {"grant_type", grant_type},
            {"client_id", client_id},
            {"client_secret", client_secret},
            {"audience", audience }
        };

    HttpResponseMessage tokenResponse = await client.PostAsync(baseAddress, new FormUrlEncodedContent(form));
        var jsonContent = await tokenResponse.Content.ReadAsStringAsync();
        Debug.Log("Response: " + jsonContent);
        Token tok = JsonConvert.DeserializeObject<Token>(jsonContent);
    Debug.Log(tok.ToString());
    return tok;
}


internal class Token
{
    [JsonProperty("access_token")]
    public string AccessToken { get; set; }

    [JsonProperty("token_type")]
    public string TokenType { get; set; }

    [JsonProperty("expires_in")]
    public int ExpiresIn { get; set; }

    [JsonProperty("refresh_token")]
    public string RefreshToken { get; set; }

    override
    public string ToString()
    {
        return "AccessToken: " + AccessToken + "; TokenType: " + TokenType + "; Expires in: " + ExpiresIn + "; Refresh Token: " + RefreshToken;
    }
}
}

Start() 方法中删除 task.Result 会阻止 Unity 在按下按钮时冻结,但我想获取令牌以在之后访问 api。

谁能告诉我为什么 Unity 死机了?

你需要使用await关键字,像这样:

Token task = await GetElibilityToken(client);

但是你也需要改变方法,像这样:

async Task Start()

实际上一直建议始终使用异步。您可以在本主题 here.

中找到更多信息

https://gametorrahod.com/unity-and-async-await/

编辑: 根据评论,似乎我们不允许将 Unity 的 Start 更改或重新定义为 async Task,因此在此情况下我仍然会使用 async void,尽管不推荐 https://docs.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming

async void Start()