【发布时间】:2020-12-02 21:54:56
【问题描述】:
我正在构建的应用程序需要调用一些在 GKE 中运行的 Api 来检索一些值。在这种情况下,它是设置的默认值。
由于所需的数据库尚未设置,GKE 中的 Api 当前处于崩溃循环中。在 Api 出现故障的情况下,就像现在一样,应用程序应该只是在请求上超时,它从我的代码中应该可以处理得很好。
问题是,它永远不会超时,即使在 Postman 中完成的完全相同的请求在大约 10 秒后超时。 我的类的构造函数,对 Api 的调用如下所示。忽略 IHandler,如下所示,它适用于我的 Entity Framework Core。问题出在方法“ApiGet”内部。 'ApiGet' 方法是从我的 Get 方法中调用的,我不打算展示它,因为那是一种方法的怪物(112 行...)
public abstract class ControllerProxy
{
protected RestClient Client { get; }
protected IHandler Handler { get; }
protected ControllerProxy(IHandler handler, string baseAddress, string controller)
{
Client = new RestClient(new Uri($"{baseAddress}api/{controller}/"));
Handler = handler;
}
}
public class SettingsControllerProxy : ControllerProxy, ISettingsController<SettingProxy>
{
public SettingsControllerProxy(IHandler handler, string baseAddress, string controller) : base(handler, baseAddress, controller)
{
Client.ThrowOnAnyError = true;
Client.Timeout = 1000;
}
private async Task<IEnumerable<SettingProxy>> ApiGet(SettingProxy entity)
{
// Creates request for the settings matching the ValueType and key
var request = new RestRequest() {Timeout = 1000, ReadWriteTimeout = 1000, Method = Method.GET }.AddQueryParametersFromObject(entity,
new List<string>() {nameof(entity.ValueType), nameof(entity.Key)});
try
{
var response = await Client.ExecuteTask(request, TimeSpan.FromSeconds(10));
// Returns the Deserialized list of Settings if it is successful, otherwise gives an empty list. Check for empty list on the return side.
return response.IsSuccessful ? JsonConvert.DeserializeObject<List<SettingProxy>>(response.Content) : new List<SettingProxy>();
}
catch (Exception e)
{
Logging.Log(LogType.Warning, $"Caught a {e.GetType().Name} in {nameof(ApiGet)}; " +
$"Exception => {e}; returning an empty list to caller...");
return new List<SettingProxy>();
}
}
...
}
下面可以看到方法“AddQueryParametersFromObject”以供参考,然后是“ExecuteTask”。当我在 ExecuteTask 中调用 ExecuteAsync 时,它会停止并且永远不会继续。
public static IRestRequest AddQueryParametersFromObject<T>(this IRestRequest request, T input,
IEnumerable<string> propertyNames) where T : class
{
var properties = typeof(T).GetProperties().Where(x => propertyNames.Any(z => x.Name == z)).ToList();
return properties.Aggregate(request, (current, info) => current.AddQueryParameter(info.Name, info.GetValue(input).ToString()));
}
public static async Task<IRestResponse> ExecuteTask(this IRestClient client, IRestRequest request, TimeSpan taskTimeout = default)
{
var TaskCompletionSource = new TaskCompletionSource<IRestResponse>();
var source = new CancellationTokenSource();
if (taskTimeout != default)
source.CancelAfter(taskTimeout);
try
{
var response = await client.ExecuteAsync(request, source.Token);
if (response.ResponseStatus == ResponseStatus.Error)
TaskCompletionSource.SetException(response.ErrorException);
else
TaskCompletionSource.SetResult(response);
}
catch (Exception e)
{
TaskCompletionSource.SetException(e);
}
return await TaskCompletionSource.Task;
}
RestSharp 是否根本不适用于 Xamarin? 我想继续使用 RestSharp,因为用它创建请求似乎要容易得多,超过 HttpClient。
我查看了“FubarCoder.RestSharp.Portable”Nuget 包,但由于它自上次更新以来已经有一段时间了,我不愿意使用它。
如果还有什么我可以提供给你的,请随意询问更多细节。
【问题讨论】:
-
看起来有关于超时问题的报告,如果您没有使用值得升级的最新版本并尝试github.com/FubarDevelopment/restsharp.portable/issues/82
-
我应该更清楚地说明我没有使用nuget.org/packages/FubarCoder.RestSharp.Portable,而是使用普通的(nuget.org/packages/restsharp),它仍在更新中。
标签: c# xamarin.forms xamarin.android asp.net-core-webapi restsharp