另一种解决方案:Refit 中的一个测试使用了这种方法。在 nuget 中添加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 解决方案:
为您的任务创建扩展方法:
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>
返回值离开接口。在 API 中:
try
{
await _server.ListGasLines().TimeoutAfter(TimeSpan.FromSeconds(10));
}
catch(System.TimeoutException e)
{
Console.WriteLine("Timeout: " + e.Message);
}