为什么当 RestClient.Execute 工作时,使用 RestClient.ExecuteAsync 和 awa



我目前正在与Personio集成以获取员工数据。

下面的解决方案不是等待响应,而是在代码中注释的点突然跳出第二种方法:

using Personio.Client.Configuration;
using Personio.Client.Exceptions;
using Personio.Client.Models.Data;
using LanguageExt;
using Newtonsoft.Json;
using RestSharp;
namespace Enpal.Personio.Client;
public class PersonioCompanyEmployeesClient
{
private readonly PersonioAuthorizationClient _authorizationClient;
private readonly PersonioConfig _personioConfig;
private readonly RestClient _restClient;
public PersonioCompanyEmployeesClient(PersonioAuthorizationClient authorizationClient, PersonioConfig personioConfig, RestClient restClient)
{
_authorizationClient = authorizationClient;
_personioConfig = personioConfig;
_restClient = restClient;
}
public TryAsync<List<Record>> TryGet(EmployeeRequestOptions options) =>
_authorizationClient.WithAuthorization<List<Record>>(token =>
{
_restClient.BaseUrl = new Uri(_personioConfig.BaseUrl, "/v1/company/employees");
_restClient.Timeout = -1;
IRestRequest request = new RestRequest(Method.GET)
.AddQueryParameter("limit", options.MaximumRecordCount.ToString())
.AddQueryParameter("offset", options.PageOffset.ToString())
.AddHeader("Accept", "application/json")
.AddHeader("Authorization", $"Bearer {token.Value}");
return GetRecordsAsync(request);
});
private async Task<List<Record>> GetRecordsAsync(IRestRequest request)
{
IRestResponse<RecordRequestResponse> requestResponse = await _restClient.ExecuteAsync<RecordRequestResponse>(request);
// Nothing below this line is ever executed!
if (requestResponse.IsSuccessful)
{
RecordRequestResponse? employeesResponse = JsonConvert.DeserializeObject<RecordRequestResponse>(requestResponse.Content);
return (employeesResponse != null && employeesResponse.WasSuccessful)
? employeesResponse.Records
.ToList()
: throw new PersonioRequestException("Connected to Personio, but could not get records.");
}
else
{
throw (requestResponse.ErrorException != null)
? new PersonioRequestException("Could not get records from Personio.", requestResponse.ErrorException)
: new PersonioRequestException("Could not get records from Personio.  Reason unknown.");
}
}
}

但是,我可以使用同步方法使此解决方案工作,如下所示:

public TryAsync<List<Record>> TryGet(EmployeeRequestOptions options) =>
_authorizationClient.WithAuthorization<List<Record>>(token =>
{
_restClient.BaseUrl = new Uri(_personioConfig.BaseUrl, "/v1/company/employees");
_restClient.Timeout = -1;
IRestRequest request = new RestRequest(Method.GET)
.AddQueryParameter("limit", options.MaximumRecordCount.ToString())
.AddQueryParameter("offset", options.PageOffset.ToString())
.AddHeader("Accept", "application/json")
.AddHeader("Authorization", $"Bearer {token.Value}");
return GetRecordsAsync(request);
});
private async Task<List<Record>> GetRecordsAsync(IRestRequest request)
{
IRestResponse<RecordRequestResponse> requestResponse = await _restClient.ExecuteAsync<RecordRequestResponse>(request);
if (requestResponse.IsSuccessful)
{
RecordRequestResponse? employeesResponse = JsonConvert.DeserializeObject<RecordRequestResponse>(requestResponse.Content);
return (employeesResponse != null && employeesResponse.WasSuccessful)
? employeesResponse.Records
.ToList()
: throw new PersonioRequestException("Connected to Personio, but could not get records.");
}
else
{
throw (requestResponse.ErrorException != null)
? new PersonioRequestException("Could not get records from Personio.", requestResponse.ErrorException)
: new PersonioRequestException("Could not get records from Personio.  Reason unknown.");
}
}

唯一的更改:

  1. GetRecords()使用Execute而不是ExecuteAsync
  2. GetRecords()返回List<Record>而不是Task<List<Record>>
  3. TryGet()GetRecordsAsync(request)Task.FromResult()包裹,然后再归还。

在查看 restsharp 的文档后,ExecuteAsync不会引发异常,而是填充response.ErrorExceptionresponse.ErrorMessage如果response.IsSuccessful等于 false,因此您应该首先检查response.IsSuccessful属性值。

更多细节可以在这里找到 - https://restsharp.dev/intro.html#content-type

我必须补充一点,RestSharp 的异步请求在最后一个版本之前都很混乱。您可以快速浏览一下HttpWebRequest如何处理异步调用,以及 RestSharp 为管理它们所做的工作,这是硬核的。我知道它对某些人有效,但可以肯定的是,问题就在那里。

如果它仍然与您相关,我建议您迁移到 v107。您使用的那些接口已经消失了,不确定这对您来说会有多大的问题。但是所有的同步方法都消失了,它现在是完全异步的,它可以工作。

我遇到了完全相同的问题,事实证明原因是因为我的链中隐藏了一个同步调用。所以这行:return GetRecordsAsync(request);需要有一个等待,这意味着 TryAsync 也应该是一个异步调用。我过去遇到过类似的问题,从上到下没有异步会导致问题。最简单的解决方案是使所有内容异步,尽管还有其他可能的解决方案

相关内容

  • 没有找到相关文章

最新更新