Refit库如何设置超时
How to set timeout in Refit library
我在我的 Xamarin 应用程序中使用 Refit 库,我想为请求设置 10 秒超时。有没有办法在改装中做到这一点?
接口:
interface IDevice
{
[Get("/app/device/{id}")]
Task<Device> GetDevice(string id, [Header("Authorization")] string authorization);
}
调用 API
var device = RestService.For<IDevice>("http://localhost");
var dev = await device.GetDevice("15e2a691-06df-4741-b26e-87e1eecc6bd7", "Bearer OAUTH_TOKEN");
我终于找到了一种在 Refit 中设置请求超时的方法。我用了CancelationToken
。这是添加 CancelationToken
后的修改代码
接口:
interface IDevice
{
[Get("/app/device/{id}")]
Task<Device> GetDevice(string id, [Header("Authorization")] string authorization, CancellationToken cancellationToken);
}
调用 API:
var device = RestService.For<IDevice>("http://localhost");
CancellationTokenSource tokenSource = new CancellationTokenSource();
tokenSource.CancelAfter(10000); // 10000 ms
CancellationToken token = tokenSource.Token;
var dev = await device.GetDevice("15e2a691-06df-4741-b26e-87e1eecc6bd7", "Bearer OAUTH_TOKEN", token);
它适合我。我不知道这是否是正确的方法。如有错误,请提出正确的方法。
接受的答案是为单个请求强制超时的正确方法,但如果您希望所有请求都有一个一致的超时值,您可以传递预配置的 HttpClient
及其 Timeout
属性 集:
var api = RestService.For<IDevice>(new HttpClient
{
BaseAddress = new Uri("http://localhost"),
Timeout = TimeSpan.FromSeconds(10)
});
这是一个example project。
另一种解决方案:nuget中的tests in Refit uses this method. Add System.Reactive.Linq之一。
然后在接口规范中:
interface IDevice
{
[Get("/app/device/{id}")]
IObservable<Device> GetDevice(string id, [Header("Authorization")] string authorization);
}
并且在 API:
try
{
await device.GetDevice("your_parameters_here").Timeout(TimeSpan.FromSeconds(10));
}
catch(System.TimeoutException e)
{
Console.WriteLine("Timeout: " + e.Message);
}
+1 个来自 here 的解决方案:
为您的任务创建扩展方法:
public static class TaskExtensions
{
public static async Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, TimeSpan timeout)
{
using (var timeoutCancellationTokenSource = new CancellationTokenSource())
{
var completedTask = await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token));
if (completedTask == task)
{
timeoutCancellationTokenSource.Cancel();
return await task; // Very important in order to propagate exceptions
}
else
{
throw new TimeoutException("The operation has timed out.");
}
}
}
}
接口可以使用 Task<Device>
return 值保留。在 API:
try
{
await _server.ListGasLines().TimeoutAfter(TimeSpan.FromSeconds(10));
}
catch(System.TimeoutException e)
{
Console.WriteLine("Timeout: " + e.Message);
}
我在我的 Xamarin 应用程序中使用 Refit 库,我想为请求设置 10 秒超时。有没有办法在改装中做到这一点?
接口:
interface IDevice
{
[Get("/app/device/{id}")]
Task<Device> GetDevice(string id, [Header("Authorization")] string authorization);
}
调用 API
var device = RestService.For<IDevice>("http://localhost");
var dev = await device.GetDevice("15e2a691-06df-4741-b26e-87e1eecc6bd7", "Bearer OAUTH_TOKEN");
我终于找到了一种在 Refit 中设置请求超时的方法。我用了CancelationToken
。这是添加 CancelationToken
接口:
interface IDevice
{
[Get("/app/device/{id}")]
Task<Device> GetDevice(string id, [Header("Authorization")] string authorization, CancellationToken cancellationToken);
}
调用 API:
var device = RestService.For<IDevice>("http://localhost");
CancellationTokenSource tokenSource = new CancellationTokenSource();
tokenSource.CancelAfter(10000); // 10000 ms
CancellationToken token = tokenSource.Token;
var dev = await device.GetDevice("15e2a691-06df-4741-b26e-87e1eecc6bd7", "Bearer OAUTH_TOKEN", token);
它适合我。我不知道这是否是正确的方法。如有错误,请提出正确的方法。
接受的答案是为单个请求强制超时的正确方法,但如果您希望所有请求都有一个一致的超时值,您可以传递预配置的 HttpClient
及其 Timeout
属性 集:
var api = RestService.For<IDevice>(new HttpClient
{
BaseAddress = new Uri("http://localhost"),
Timeout = TimeSpan.FromSeconds(10)
});
这是一个example project。
另一种解决方案:nuget中的tests in Refit uses this method. Add System.Reactive.Linq之一。 然后在接口规范中:
interface IDevice
{
[Get("/app/device/{id}")]
IObservable<Device> GetDevice(string id, [Header("Authorization")] string authorization);
}
并且在 API:
try
{
await device.GetDevice("your_parameters_here").Timeout(TimeSpan.FromSeconds(10));
}
catch(System.TimeoutException e)
{
Console.WriteLine("Timeout: " + e.Message);
}
+1 个来自 here 的解决方案:
为您的任务创建扩展方法:
public static class TaskExtensions
{
public static async Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, TimeSpan timeout)
{
using (var timeoutCancellationTokenSource = new CancellationTokenSource())
{
var completedTask = await Task.WhenAny(task, Task.Delay(timeout, timeoutCancellationTokenSource.Token));
if (completedTask == task)
{
timeoutCancellationTokenSource.Cancel();
return await task; // Very important in order to propagate exceptions
}
else
{
throw new TimeoutException("The operation has timed out.");
}
}
}
}
接口可以使用 Task<Device>
return 值保留。在 API:
try
{
await _server.ListGasLines().TimeoutAfter(TimeSpan.FromSeconds(10));
}
catch(System.TimeoutException e)
{
Console.WriteLine("Timeout: " + e.Message);
}