Остановить операцию, если запрошен CancellationTokenC#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Остановить операцию, если запрошен CancellationToken

Сообщение Anonymous »

У меня была такая проблема, в моем мобильном приложении, если нажать выход в момент синхронизации, происходит сбой.
Синхронизация - это синхронизация все состояние моего приложения и вывод информации.
Выход - после него очищаем все данные и сервисы.
Оказывается, когда мы нажимаем выйти во время синхронизации (2 секунды), мы все равно можем попасть в цикл while и получить доступ к полю UpdateFrequencyInSeconds, и произойдет сбой.
private async void ThreadSync(CancellationToken token)
{
while (token.IsCancellationRequested is false)
{
await Sync().ConfigureAwait(false);
await Task.Delay(organizationAppSettingsService.UpdateFrequencyInSeconds * 1000).ConfigureAwait(false);
}
}

Я, конечно, нашел решение, но оно не совсем чистое и идеальное.
Вот как оно будет работать.
private async void ThreadSync(CancellationToken token)
{
while (token.IsCancellationRequested is false)
{
var updateFrequencyInSeconds = organizationAppSettingsService.UpdateFrequencyInSeconds * 1000;
await Sync().ConfigureAwait(false);
await Task.Delay(updateFrequencyInSeconds).ConfigureAwait(false);
}
}

Это тоже сработает, но это некрасиво.
private async void ThreadSync(CancellationToken token)
{
while (token.IsCancellationRequested is false)
{
await Sync().ConfigureAwait(false);
if (token.IsCancellationRequested is false)
await Task.Delay(organizationAppSettingsService.UpdateFrequencyInSeconds * 1000).ConfigureAwait(false);
}
}

Есть ли какой-нибудь элегантный способ не выполнять получение поля, если токен отменен?
Это тоже не работает, сначала делается запрос, затем только токен сделано.
await Task.Delay(organizationAppSettingsService.UpdateFrequencyInSeconds * 1000, token).ConfigureAwait(false);

Я пытаюсь найти лучшее решение для исправления ошибки, придумал три варианта, но они не совсем чисты.
Метод синхронизации
public async Task Sync()
{
if (networkManager.IsNetworkAvailable is false || IsSyncInProgress ||
(DateTime.Now - _lastSyncedTime).TotalSeconds < organizationAppSettingsService.UpdateFrequencyInSeconds)
return;
IsSyncInProgress = true;
_logger.LogInformation($"[BackgroundSync] Updating");
var waiting = Task.Delay(2000);
ShowSyncProgress?.Invoke();
try
{
UpdateLocation();

await ordersRepository.UpdateOrders(_courierLocations, _ordersDtos).ConfigureAwait(false);
var updateServiceInfo = !_lastServiceInfoUpdated.HasValue ||
(DateTime.Now - _lastServiceInfoUpdated.Value).TotalSeconds >=
IAppSettingsService.DefaultServiceRequestFrequency;
if (updateServiceInfo)
{
await UpdatePaymentTypes().ConfigureAwait(false);
_lastServiceInfoUpdated = DateTime.Now;
}

Synced = true;

_courierLocations.Clear();
var orders = Orders?.Where(x => (DateTime.Now - x.DeliveryDate).TotalHours < 24).ToList();
if (orders is null || orders.Any() is false)
{
SyncCompleted?.Invoke();
return;
}

await waiting;
SyncCompleted?.Invoke();
}
catch (SessionExpiredException)
{
await RecoverTransportSession().ConfigureAwait(false);
}
catch (Exception ex)
{
CatchSyncException(ex);
}
finally
{
_lastSyncedTime = DateTime.Now;

IsSyncInProgress = false;
HideSyncProgress?.Invoke();
_logger.LogInformation("[BackgroundSync] Update completed");
}


Подробнее здесь: https://stackoverflow.com/questions/787 ... -requested
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»