У меня была такая проблема, в моем мобильном приложении, если нажать выход в момент синхронизации, происходит сбой.
Синхронизация - это синхронизация все состояние моего приложения и вывод информации.
Выход - после него очищаем все данные и сервисы.
Оказывается, когда мы нажимаем выйти во время синхронизации (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
Остановить операцию, если запрошен CancellationToken ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как правильно отменить асинхронную операцию, которая не принимает CancellationToken?
Anonymous » » в форуме C# - 0 Ответы
- 28 Просмотры
-
Последнее сообщение Anonymous
-
-
-
Запрошен фатальный выход из программы при удалении моего ColorResources()
Anonymous » » в форуме C++ - 0 Ответы
- 67 Просмотры
-
Последнее сообщение Anonymous
-