У меня есть код, который создает токен отмены
public partial class CardsTabViewModel : BaseViewModel
{
public CancellationTokenSource cts;
public async Task OnAppearing()
{
cts = new CancellationTokenSource(); // << runs as part of OnAppearing()
Код, который использует это:
await GetCards(cts.Token);
public async Task GetCards(CancellationToken ct)
{
while (!ct.IsCancellationRequested)
{
App.viewablePhrases = App.DB.GetViewablePhrases(Settings.Mode, Settings.Pts);
await CheckAvailability();
}
}
и код, который впоследствии отменяет этот токен отмены, если пользователь отходит от экрана, на котором выполняется приведенный выше код:
public void OnDisappearing()
{
cts.Cancel();
Что касается отмены, это правильный способ отменить токен, когда он используется в Задаче?
В частности, я проверил этот вопрос:
Использование свойства IsCancellationRequested?
и это заставляет меня думать, что я не делаю отмену правильным способом или возможно способом, который может вызвать исключение.
Кроме того, в этом случае после того, как я отменил, тогда я должен делать cts.Dispose ()?
c#
xamarin
xamarin.forms
alan2
источник
источник
Ответы:
CancellationTokenSource.Cancel()
является действительным способом начать отмену.Опрос
ct.IsCancellationRequested
избегает бросковOperationCanceledException
. Поскольку это опрос, он требует, чтобы итерация цикла завершилась до того, как он ответит на запрос отмены.Если
GetViewablePhrases()
иCheckAvailability()
можно изменить, чтобы принять aCancellationToken
, это может сделать отмену быстрее, чтобы ответить, за счетOperationCanceledException
броска."Должен ли я делать cts.Dispose ()?" это не так просто ...
Это скорее руководство, чем правило.
Task
сам по себе одноразовый, но вряд ли когда-либо напрямую расположен в коде.Существуют случаи (когда
WaitHandle
используются обработчики обратного вызова или отмены), когда утилизацияcts
освобождает ресурс / удаляет корень GC, который в противном случае был бы освобожден только финализатором. Они не относятся к вашему коду в том виде, в каком он есть, но могут и в будущем.Добавление вызова
Dispose
после отмены гарантирует, что эти ресурсы будут быстро освобождены в будущих версиях кода.Тем не менее, вам придется либо дождаться завершения кода, который использует,
cts
прежде чем вызывать dispose, либо изменить код, чтобы справляться сObjectDisposedException
использованиемcts
(или его токена) после удаления.источник
CancellationToken
параметр), вы можете избавиться от него,WaitHandle
пока другой поток активно ожидает его :(Dispose
изOnDisappearing
.Cancel
...Cancel
- это внутренний таймер (если используется).В целом, я вижу правильное использование токена отмены в вашем коде, но в соответствии с шаблоном асинхронного задания ваш код может быть отменен не сразу.
Для немедленного ответа код блокировки также следует отменить
Это зависит от вас, если вы должны утилизировать, если в прерванном коде зарезервировано много ресурсов памяти, вы должны это сделать.
источник
Я бы порекомендовал вам взглянуть на один из классов .net, чтобы полностью понять, как обрабатывать методы ожидания с CanncelationToken, я взял SeamaphoreSlim.cs
Вы также можете просмотреть весь класс здесь, https://referencesource.microsoft.com/#mscorlib/system/threading/SemaphoreSlim.cs,6095d9030263f169
источник