带有 await GetAsync API 调用的方法在没有返回结果或 运行 方法中的所有代码的情况下退出
Method with await GetAsync API call exits without a returning a result or running all code in the method
借鉴https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client中的Get方法,我写了以下内容。作为 C# 的新手,我假设 await 会完成 API 调用然后继续,但是发生的事情是该行执行然后退出方法而没有 运行 另一行代码(if 语句,return).我可能也假设了其他事情,这让我陷入了这种困境。
代码应该是什么才能始终从 API 调用中获得响应并反序列化 Json 以便我可以检索我实际需要的 2 位数据?
对我的代码提出的任何其他改进建议也非常感谢。
方法调用:
var ReturnedData = GetProductAsync(companyCode);
方法:
//API Call method - https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client
static HttpClient client = new HttpClient();
static async Task<ReturnedAPIdata> GetProductAsync(string CoCode)
{
// TODO - This key will need to be taken out of the code and put in a config file or something
string DavesKey = "abc123";
string path = "http://api.marketstack.com/v1/eod?access_key=" + DavesKey + "&symbols=" + CoCode + ".XASX&sort=DESC&limit=1&offset=0";
ReturnedAPIdata ThatAPIdata = null;
HttpResponseMessage response = await client.GetAsync(path);
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
// If we have an API response, deserialise the Json data... somehow
//ThatAPIdata = await response.Content.ReadAsAsync<ReturnedAPIdata>(); // ReadAsAsync has been deprecated, but not replaced. Handy
string responseBody = await response.Content.ReadAsStringAsync();
// Which one of these fuckers actually works. Use an API, they said. It'll be fun, they said. ARG!
ReturnedAPIdata Arses = System.Text.Json.JsonSerializer.Deserialize<ReturnedAPIdata>(responseBody); // attempt 3
List<ReturnedAPIdata> Cock = JsonConvert.DeserializeObject<List<ReturnedAPIdata>>(responseBody); // attempt 2
ReturnedAPIdata Balls = JsonConvert.DeserializeObject<ReturnedAPIdata>(responseBody); // attempt 1
}
Console.WriteLine("FFFFFFFFFfffff....");
return ThatAPIdata;
}
最后的 Conrole.Writeline 只是一个断点,所以我可以评估哪种反序列化尝试效果最好,我还没有看到停止。
如果下面的代码是运行:
static void Main(string[] args)
{
Console.WriteLine("Before calling async method");
GetProductAsync();
Console.WriteLine("After calling async method");
}
static async Task<string> GetProductAsync()
{
await Task.Delay(5000);
Console.WriteLine("Inside async method after await");
return "Got all Products";
}
以下结果打印到控制台:
Before calling async method
System.Threading.Tasks.Task`1[System.String]
After calling async method
因此即使方法 GetProductAsync
被定义为 async
并且等待 5 秒,执行也会失败,还要注意在异步方法内部有一个 Console.WriteLine("Inside async method after await");
这也不会被打印出来!而且 return 值也不会打印出来!
那么这里发生了什么?仅仅因为该方法被定义为 async 并且其中有一个 await 并不意味着调用者保证异步执行!
特别是调用它的 Main
方法没有 await
结果,所以这就是它失败的原因。
现在,如果代码已更改且 Main 正在等待 GetProductAsync
方法:
static async Task Main(string[] args)
{
Console.WriteLine("Before calling async method");
var result = await GetProductAsync();
Console.WriteLine("After calling async method");
Console.WriteLine(result);
}
static async Task<string> GetProductAsync()
{
await Task.Delay(5000);
Console.WriteLine("Inside async method after await");
return "Got all Products";
}
现在打印到控制台的结果是:
Before calling async method
Inside async method after await
After calling async method
Got all Products
所以在这种情况下,在 main 内部正确等待结果,执行 return 给调用者 ,现在可以自由地继续执行其他任务,例如更新 GUI(在这个简单的控制台应用程序中不是这种情况)。
希望这说明了这里发生的事情,基本上调用者,在这种情况下 Main
,也需要等待异步 GetProductAsync
方法的结果才能看到结果。
这篇文章很好地解释了各种陷阱和问题!无需深入
https://www.pluralsight.com/guides/understand-control-flow-async-await
借鉴https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client中的Get方法,我写了以下内容。作为 C# 的新手,我假设 await 会完成 API 调用然后继续,但是发生的事情是该行执行然后退出方法而没有 运行 另一行代码(if 语句,return).我可能也假设了其他事情,这让我陷入了这种困境。
代码应该是什么才能始终从 API 调用中获得响应并反序列化 Json 以便我可以检索我实际需要的 2 位数据?
对我的代码提出的任何其他改进建议也非常感谢。
方法调用:
var ReturnedData = GetProductAsync(companyCode);
方法:
//API Call method - https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client
static HttpClient client = new HttpClient();
static async Task<ReturnedAPIdata> GetProductAsync(string CoCode)
{
// TODO - This key will need to be taken out of the code and put in a config file or something
string DavesKey = "abc123";
string path = "http://api.marketstack.com/v1/eod?access_key=" + DavesKey + "&symbols=" + CoCode + ".XASX&sort=DESC&limit=1&offset=0";
ReturnedAPIdata ThatAPIdata = null;
HttpResponseMessage response = await client.GetAsync(path);
response.EnsureSuccessStatusCode();
if (response.IsSuccessStatusCode)
{
// If we have an API response, deserialise the Json data... somehow
//ThatAPIdata = await response.Content.ReadAsAsync<ReturnedAPIdata>(); // ReadAsAsync has been deprecated, but not replaced. Handy
string responseBody = await response.Content.ReadAsStringAsync();
// Which one of these fuckers actually works. Use an API, they said. It'll be fun, they said. ARG!
ReturnedAPIdata Arses = System.Text.Json.JsonSerializer.Deserialize<ReturnedAPIdata>(responseBody); // attempt 3
List<ReturnedAPIdata> Cock = JsonConvert.DeserializeObject<List<ReturnedAPIdata>>(responseBody); // attempt 2
ReturnedAPIdata Balls = JsonConvert.DeserializeObject<ReturnedAPIdata>(responseBody); // attempt 1
}
Console.WriteLine("FFFFFFFFFfffff....");
return ThatAPIdata;
}
最后的 Conrole.Writeline 只是一个断点,所以我可以评估哪种反序列化尝试效果最好,我还没有看到停止。
如果下面的代码是运行:
static void Main(string[] args)
{
Console.WriteLine("Before calling async method");
GetProductAsync();
Console.WriteLine("After calling async method");
}
static async Task<string> GetProductAsync()
{
await Task.Delay(5000);
Console.WriteLine("Inside async method after await");
return "Got all Products";
}
以下结果打印到控制台:
Before calling async method
System.Threading.Tasks.Task`1[System.String]
After calling async method
因此即使方法 GetProductAsync
被定义为 async
并且等待 5 秒,执行也会失败,还要注意在异步方法内部有一个 Console.WriteLine("Inside async method after await");
这也不会被打印出来!而且 return 值也不会打印出来!
那么这里发生了什么?仅仅因为该方法被定义为 async 并且其中有一个 await 并不意味着调用者保证异步执行!
特别是调用它的 Main
方法没有 await
结果,所以这就是它失败的原因。
现在,如果代码已更改且 Main 正在等待 GetProductAsync
方法:
static async Task Main(string[] args)
{
Console.WriteLine("Before calling async method");
var result = await GetProductAsync();
Console.WriteLine("After calling async method");
Console.WriteLine(result);
}
static async Task<string> GetProductAsync()
{
await Task.Delay(5000);
Console.WriteLine("Inside async method after await");
return "Got all Products";
}
现在打印到控制台的结果是:
Before calling async method
Inside async method after await
After calling async method
Got all Products
所以在这种情况下,在 main 内部正确等待结果,执行 return 给调用者 ,现在可以自由地继续执行其他任务,例如更新 GUI(在这个简单的控制台应用程序中不是这种情况)。
希望这说明了这里发生的事情,基本上调用者,在这种情况下 Main
,也需要等待异步 GetProductAsync
方法的结果才能看到结果。
这篇文章很好地解释了各种陷阱和问题!无需深入 https://www.pluralsight.com/guides/understand-control-flow-async-await