У меня была такая проблема, в моем мобильном приложении, если нажать выход в момент синхронизации, происходит сбой.
Синхронизация - это синхронизация все состояние моего приложения и вывод информации.
Выход - после него очищаем все данные и сервисы.
Оказывается, когда мы нажимаем выйти во время синхронизации (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#
Место общения программистов C#
-
Anonymous
1721735146
Anonymous
У меня была такая проблема, в моем мобильном приложении, если нажать выход в момент синхронизации, происходит сбой.
[b]Синхронизация[/b] - это синхронизация все состояние моего приложения и вывод информации.
[b]Выход[/b] - после него очищаем все данные и сервисы.
Оказывается, когда мы нажимаем [b]выйти[/b] во время синхронизации (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");
}
Подробнее здесь: [url]https://stackoverflow.com/questions/78783119/stop-operation-if-cancellationtoken-is-requested[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия