Expose cancellable async methods in clients through an interface
IHttpRestClientAsync exposes various method-specific async methods as well as SendAsync.
SendAsync has a cancellation token parameter in its signature:
Task<TResponse> SendAsync<TResponse>(string httpMethod, string absoluteUrl, object request, CancellationToken token = default);
while other methods (GetAsync, PostAsync etc) don't
Implementations of IHttpRestClientAsync (like JsonHttpClient) do have the methods which support then token:
public Task<TResponse> GetAsync<TResponse>(IReturn<TResponse> requestDto, CancellationToken token) =>
SendAsync<TResponse>(HttpMethods.Get, ResolveTypedUrl(HttpMethods.Get, requestDto), null, token);
and in fact all the method-specific implementations just call SendAsync under the hood.
Without token-aware methods exposed through an interface I cannot use them in a depencency-injected IServiceClient and its derivatives. They are only usable if you access JsonHttpClient directly and not through its interfaces.
Right now I'm using this workaround in my DI setup:
public interface ICancellableHttpRestClientAsync : IHttpRestClientAsync
{
Task<TResponse> GetAsync<TResponse>(IReturn<TResponse> requestDto, CancellationToken token);
Task<TResponse> PostAsync<TResponse>(IReturn<TResponse> requestDto, CancellationToken token);
Task<TResponse> PutAsync<TResponse>(IReturn<TResponse> requestDto, CancellationToken token);
Task PatchAsync(IReturnVoid requestDto, CancellationToken token);
Task DeleteAsync(IReturnVoid requestDto, CancellationToken token);
}
private class CancellableJsonHttpRestClientAsync : JsonHttpClient, ICancellableHttpRestClientAsync
{
public CancellableJsonHttpRestClientAsync(string baseUrl) : base(baseUrl)
{
}
}
services.AddSingleton<ICancellableHttpRestClientAsync>(new CancellableJsonHttpRestClientAsync(myEndpoint));
Why not expose these methods in a library-provided interface?

Yeah the clients async interfaces weren’t ideal, it started from the initial impl of the .NET WebRequest clients being implemented using the older APM model which didn’t use them. Other implementations just kept the same API.
Anyway since it’s a source-compatible change (will require a rebuild after upgrade), I’ve added an optional CancellationToken to all Async Service Client APIs in this commit:
https://github.com/ServiceStack/ServiceStack/commit/dc6a281e80987b522c218bc82ce9cfefb111ea86
This change is now available from v5.8.1 that’s now available on MyGet:
-
Alex Bolenok commented
Wow that was fast! Thanks!