我有一个以异步格式工作的简单方法,但是当我尝试将其更改为同步格式时,它就像死锁一样,永远不会返回任何内容。我知道使用异步调用更有效,但我很好奇为什么会发生这种情况。提前致谢。
这会返回一个工作结果:
if (document.getElementById("f2")) {
} else {
}
这会让程序坐下来旋转直到我杀了它:
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()
方法时,应用程序按预期运行。
答案 0 :(得分:0)
这里有两点。
首先,异步通常会在控制台应用程序中以意外的方式工作(与UI应用程序相比)。这是因为UI具有“内置”同步上下文(显然,因为它们在“主”方法等效完成执行后不会自动退出),而控制台应用程序则不会。有关如何在控制台应用程序中使用上下文来缓解此问题的说明,请参阅this article。
其次,正如Stephen Cleary关于这个主题的优秀articles之一所指出的那样,如果可以避免的话,阻止异步是一种不好的做法,因为它可能导致你所描述的各种死锁。基本上,解决这个问题的一种方法是使用async“一直向下” - 即在第二个示例中使用async / await而不是GetResult()。这个想法在异步的Microsoft documentation最佳实践中得到了回应,建议不要像在第二个代码示例中那样混合同步和异步代码。
在我与作者链接的文章中解释了混合同步和异步代码时如何发生死锁。基本上,例如,当异步方法等待与GetResults()调用相同的上下文时,就会发生这种情况。 (他的文章解释它比我好很多:))。