Reputation: 16330
I'm making a request to a WebApi as follows:
var response = client.PostAsJsonAsync(url, dto).Result;
I'm using HostingEnvironment
in the controller action so I can do the work in a background thread, and pass IIS's cancellation token to my service method, as follows:
public IHttpActionResult MyAction(SearchDto dto)
{
HostingEnvironment.QueueBackgroundWorkItem(async ct =>
{
//Do background work
var result = await myService.DoWorkAsync(dto, ct);
});
return Ok();
}
Now I want to pass a cancellation token from the client, so that the user can cancel the request, so I created a CancellationTokenSource
and did the following change on the client:
var response = client.PostAsJsonAsync(url, dto, cts.Token).Result;
And the change to the action:
public IHttpActionResult MyAction(SearchDto dto, CancellationToken ct)
{
HostingEnvironment.QueueBackgroundWorkItem(async ct =>
{
//Do background work
var result = await myService.DoWorkAsync(dto, ct);
});
return Ok();
}
My problem is the line:
HostingEnvironment.QueueBackgroundWorkItem(async ct =>
If I need to the use the ct
I pass to the action, how am I going to use the ct
that IIS needs to pass to the background thread?
Upvotes: 4
Views: 2383
Reputation: 62532
What you need to do is combine the two cancellation tokens you've got, the first from the client and the second from the HostingEnvironment
. You can do this with this CancellationTokenSource.CreateLinkedTokenSource method
public IHttpActionResult MyAction(SearchDto dto, CancellationToken ct1)
{
HostingEnvironment.QueueBackgroundWorkItem(async ct2 =>
{
using (var linkedCts = CancellationTokenSource.CreateLinkedTokenSource(ct1, ct2))
{
var result = await myService.DoWorkAsync(dto, linkedCts.Token);
}
});
return Ok();
}
Upvotes: 1