Как передать CancellationToken в действие WebApi? - PullRequest
0 голосов
/ 12 января 2019

Я делаю запрос к WebApi следующим образом:

var response = client.PostAsJsonAsync(url, dto).Result;

Я использую HostingEnvironment в действии контроллера, чтобы я мог выполнять работу в фоновом потоке и передавать токен отмены IIS моему методу обслуживания следующим образом:

public IHttpActionResult MyAction(SearchDto dto)
{
    HostingEnvironment.QueueBackgroundWorkItem(async ct =>
    {
        //Do background work
        var result = await myService.DoWorkAsync(dto, ct);
    });

    return Ok();
}

Теперь я хочу передать токен отмены от клиента, чтобы пользователь мог отменить запрос, поэтому я создал CancellationTokenSource и внес следующие изменения на клиенте:

var response = client.PostAsJsonAsync(url, dto, cts.Token).Result;

И изменение к действию:

public IHttpActionResult MyAction(SearchDto dto, CancellationToken ct)
{
    HostingEnvironment.QueueBackgroundWorkItem(async ct =>
    {
        //Do background work
        var result = await myService.DoWorkAsync(dto, ct);
    });

    return Ok();
}

Моя проблема в строке:

HostingEnvironment.QueueBackgroundWorkItem (async ct =>

Если мне нужно использовать ct, который я перехожу к действию, как я собираюсь использовать ct, который IIS должен передать в фоновый поток?

1 Ответ

0 голосов
/ 12 января 2019

Вам нужно объединить два полученных токена отмены: первый от клиента и второй от HostingEnvironment. Вы можете сделать это с помощью этого CancellationTokenSource.CreateLinkedTokenSource метода

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();
}
...