同步调用不能工作,但异步调用可以

本文关键字:调用 异步 不能 工作 同步 | 更新日期: 2023-09-27 18:08:01

我有一个以异步格式工作的简单方法,但是当我试图将其更改为同步格式时,它的行为就像死锁并且永远不会返回任何东西。我知道使用异步调用更有效,但我很好奇为什么会发生这种情况。提前感谢。

返回一个工作结果:

public static async Task getCompanyAsync(){
    var client = new getRestClient();
    var response = await companiesApi.GetCompaniesAsync(client);
    var companies = response.GetResultAsync<List<Company>>();
}

这将使程序静止并旋转,直到我终止它:

public static void getCompany(){
    var client = new getRestClient();
    var response = companiesApi.GetCompanies(client);
    var companies = response.GetResult<List<Company>>();
}
编辑:

这里是一些更详细的代码

    static void Main(string[] args)
    {
        MainAsync(args).Wait();
        Console.ReadLine();
    }
    public static async Task MainAsync(string[] args)
    {
        await getCompanyAsync();
        getCompany();
    }
    private static async Task getCompanyAsync()
    {
        var client = getApiClient();
        var companiesApi = new CompaniesApi(client);
        var response = await companiesApi.GetCompaniesAsync();
        var companyies = await response.GetResultAsync<List<Company>>();
        foreach (var company in companyies)
        {
            Console.WriteLine(company.Name);
        }
    }
    private static void getCompany()
    {
        var client = getApiClient();
        var companiesApi = new CompaniesApi(client);
        var response = companiesApi.GetCompanies();
        var companyies = response.GetResult<List<Company>>();
        foreach (var company in companyies)
        {
            Console.WriteLine(company.Name);
        }

当我将getCompany();MainAsync()方法移动到Main()方法时,应用程序按预期运行。

同步调用不能工作,但异步调用可以

有两点。

首先,异步在控制台应用程序中经常以意想不到的方式工作(与UI应用程序相比)。这是因为ui有一个"内置的"同步上下文(很明显,因为它们不会在等效的"main"方法完成执行后自动退出),而控制台应用程序没有。有关如何在控制台应用程序中使用上下文来缓解这种情况的说明,请参阅本文。

其次,正如Stephen Cleary在一篇关于该主题的优秀文章中指出的那样,如果可以避免的话,阻止异步是一种不好的做法,因为它可能导致你所描述的那种死锁。基本上,解决这个问题的一种方法是使用async"一直向下"-即在第二个示例中使用async/await而不是GetResult()。这个想法在微软关于异步最佳实践的文档中得到了回应,该文档建议不要像在第二个代码示例中那样混合使用同步和异步代码。

在我链接到作者的文章中,

解释了当您混合使用同步和异步代码时如何发生死锁。基本上,这可能发生在,例如,异步方法正在等待与GetResults()调用相同的上下文时。(不过他的文章比我解释得好得多:))。