使用Task.Result锁定应用程序的API调用

vrw*_*wim 0 c# task async-await

我有一段C#代码(它在Xamarin应用程序中,但我不认为这是相关的)初始化我的应用程序.它是这样的:

class AppController {
    public override void InitializeApp() {
        // Do stuff to initialize services & database
        checkNeedsUpdates();
    }

    void checkNeedsUpdates() {
        Task.Run(() => {
            string json = API.Call("versions").Result
            // It never gets here
        });
    }
}

class API {
    HttpClient client;

    public Task<string> Call(string endpoint) {
        // Setup headers and access token things before handing over to POST function
        return Post(/*params*/);
    }

    public async Task<string> Post(/*params*/) {
        // Setup
        return await Request(/*params*/);
    }

    public async Task<string> Request(/*params*/) {
        HttpRequestMessage message = /*setup*/;
        HttpResponseMessage result = await client.SendAsync(message);
        result.EnsureSuccessStatusCode();
        return await result.Content.ReadAsStringAsync();
    }
}
Run Code Online (Sandbox Code Playgroud)

现在奇怪的部分是,我认为应用程序的这一部分没有任何改变,我确实添加了一些代码来解决Call方法内部的refreshtokens问题.

为什么我的应用会冻结?我知道Task.Result在异步方法中使用可能会导致死锁,因为它无法安排自己或其他东西,但我没有改变任何东西或来自asyncTask

Mar*_*ell 5

最终,这种.Result行为是不确定的.而不是担心改变了什么:只需修复它......

Task.Run(async () => 
{
    string json = await API.Call("versions");
    //...
});
Run Code Online (Sandbox Code Playgroud)

现在定义良好,无论sync-context状态如何,都应该可以正常工作.

  • @Evk没有任何指定的事情会发生;**可能*死锁,它*可能*工作正常,导致同步等待 - 这发生取决于你控制之外的东西(通常); 但是:除非你知道任务已经完成,否则你不会**触及`.Result` (2认同)
  • @Evk`async void`几乎从来都不是一个好主意.如果你建议将它改为`async Task CheckNeedsUpdates()`并删除`Task.Run()`:我都是你的 (2认同)
  • @Evk是的,在某些方面我同意 - 而Task.Run对"等"等没有任何保证; 但我不能让自己提倡`async void` :) (2认同)