I have this line, which does a blocking (synchronous) web service call, and works fine:
var response = client.Execute<DataRequestResponse>(request);
(The var
represents IRestResponse<DataRequestResponse>
)
But, now I want to be able to cancel it (from another thread). (I found this similar question, but my code must stay sync - the code changes have to stay localized in this function.)
I found CancellationTokenSource
, and an ExecuteTaskAsync()
which takes a CancellationToken
. (See https://stackoverflow.com/a/21779724/841830) That sounds like it could do the job. I got as far as this code:
var cancellationTokenSource = new CancellationTokenSource();
var task = client.ExecuteTaskAsync(request, cancellationTokenSource.Token);
task.Wait();
var response = task.Result;
The last line refuses to compile, telling me it cannot do an implicit cast. So I tried an explicit cast:
IRestResponse<DataRequestResponse> response = task.Result as IRestResponse<DataRequestResponse>;
That compiles, runs, but then crashes (throws a NullReferenceException, saying "Object reference not set to an instance of an object").
(By the way, once I have this working, then the cancellationTokenSource.Token
will of course be passed in from the master thread, and I will also be adding some code to detect when an abort happened: I will throw an exception.)
My back-up plan is just to abort the whole thread this is running in. Crude, but that is actually good enough at the moment. But I'd rather be doing it "properly" if I can.
MORE INFORMATION:
The sync Execute
call is here: https://github.com/restsharp/RestSharp/blob/master/RestSharp/RestClient.Sync.cs#L55 where it ends up calling Http.AsGet()
or Http.AsPost()
, which then ends up here: https://github.com/restsharp/RestSharp/blob/master/RestSharp/Http.Sync.cs#L194
In other words, under the covers RestSharp is using HttpWebRequest.GetResponse. That has an Abort
function, but being a sync function (i.e. which does not return until the request is done) that is not much use to me!
The async counterpart of your call
var response = client.Execute<DataRequestResponse>(request);
is the public virtual Task<IRestResponse<T>> ExecuteTaskAsync<T>(IRestRequest request, CancellationToken token)
RestSharp async method.
It takes a cancellation token, and returns a task with the correct return type signature. To use it and wait for its (cancellable) completion, you could change your sample code to:
var cancellationTokenSource = new CancellationTokenSource();
// ...
var task = client.ExecuteTaskAsync<DataRequestResponse>(
request,
cancellationTokenSource.Token);
// this will wait for completion and throw on cancellation.
var response = task.Result;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With