Я работаю над переносом контроллера на асинхронный режим. Часть работы включает ожидание асинхронной отменяемой операции с одноразовым объектом с использованием токена отмены, действительного в течение всего срока действия запроса. В данном конкретном случае это WebClient.UploadStringTaskAsync(Uri uri, string data)
.
Я знаю правильный способ отменить асинхронные операции WebClient с помощью cancellationToken.Register(() => webClient.CancelAsync())
. Однако WebClient
создается в операторе using, поэтому он располагается в конце блока. В результате вызов webClient.CancelAsync()
из обратного вызова по праву приводит к предупреждению «Доступ к удаленному закрытию». Я обнаружил, что CancellationToken.Register(Action callback)
приводит к CancellationTokenRegistration
объекту, который реализует IDisposable
и отменяет регистрацию обратных вызовов при удалении. В итоге мой код выглядит так:
using (var webClient = new WebClient())
using (cancellationToken.Register(() => webClient.CancelAsync())
{
await webClient.UploadStringTaskAsync(uri, data);
}
// cancellationToken can be cancelled later.
Я создал консольное приложение, чтобы показать, что код с тем же духом работает, и отмена токена после удаления одноразового объекта и регистрации токена не приводит к вызову обратного вызова одноразового объекта. Однако я хочу быть уверен: это правильно и безопасно?
Изменить: Полагаю, мне следует немного перефразировать свой вопрос. Какое стандартное решение для использования токена отмены для отмены асинхронной операции на одноразовом объекте, где операция поддерживает отмену только через регистрацию обратного вызова?
CancellationTokenRegistration
будет вызываться в противном случае? - person Dai   schedule 10.05.2017CancellationToken
является общедоступным, вы можете проверить его самостоятельно и точно знать, что он будет делать в вашем конкретном сценарии. На ваш вопрос невозможно ответить как есть. Судя по опубликованному вами коду, кажется маловероятным, что вашWebClient
может быть удален, пока обратный вызов все еще был зарегистрирован, поскольку это снова будут правила спецификации C #. Но как узнать наверняка, что делает остальная часть кода? - person Peter Duniho   schedule 11.05.2017WebClient
, сам по себе не использует обратный вызов для отмены. Я думаю, что, возможно, вы имеете в виду, что для отмены с помощьюCancelToken
требуется регистрация обратного вызова, но это совсем не ясно из того, что вы на самом деле написали, и, безусловно, есть другие механизмы, которые можно использовать. - person Peter Duniho   schedule 11.05.2017