Akavache GetAndFetchLatest никогда не вызывает fetchfunc

Работаем с Акаваче последние пару дней. У меня есть несколько методов, которые используют метод GetAndFetchLatest, но некоторые методы никогда не вызывают fetchFunc, и проблема возникает случайно для всех функций.

 public async Task<ChecklistModel> GetChecklistTypes()
 {            
        var ChecklistTypesCache = 
        BlobCache.LocalMachine.GetAndFetchLatest("ChecklistTypes",
                                  () => GetChecklistTypesRemote(),
                                  offset =>
                                  {
                                      TimeSpan elapsed = DateTimeOffset.Now - offset;
                                      return elapsed > new TimeSpan(hours: 0, minutes: 5, seconds: 0);
                                  });
        ChecklistTypesCache.Subscribe(subsribedData =>
        {
            _checkilstModel = subsribedData;
        });
        _checkilstModel = await ChecklistTypesCache.FirstOrDefaultAsync();
        return _checkilstModel;
 }

 public async Task<ChecklistModel> GetChecklistTypesRemote()
 {
     //do something
 }

Кто-нибудь сталкивался с этой проблемой? Нужно ли делать что-то еще, чтобы работать? Как это исправить?

"Обновленный код"

  public async Task<IEnumerable<ChecklistModel.Checklist>> 
  GetChecklistTypesCache()
   {
        IEnumerable<ChecklistModel.Checklist> checklistModel = null;
        var ChecklistTypesCache = 
        BlobCache.LocalMachine.GetAndFetchLatest("ChecklistAccessLevels",
                                 () => GetChecklistTypesRemote(),
                                 offset =>
                                 {
                                     TimeSpan elapsed = DateTimeOffset.Now - 
        offset;
                                     return elapsed > new TimeSpan(hours: 0, 
        minutes: 5, seconds: 0);
                                 });
        ChecklistTypesCache.Subscribe(subsribedData =>
        {
            checklistModel = subsribedData;
        });
        checklistModel = await ChecklistTypesCache.FirstOrDefaultAsync();
        return checklistModel;
    }

     public async Task<IEnumerable<ChecklistModel.Checklist>> GetChecklistTypesRemote()
    {
        //do something
    }

2 ответа

Решение

Поэтому, чтобы уточнить, что сказал @Geoffrey Huntley, немного сложно сформировать ответ, потому что то, как вы это делаете (даже в Gist), на самом деле не имеет смысла "Реактивно". GetAndFetchLatest не имеет никакого смысла в использовании, если вы собираетесь использовать шаблоны обещания / асинхронизации / ожидания... Если вы собираетесь использовать GetAndFetchLatest, ваш код будет выглядеть примерно так

    public IObservable<ChecklistModel.Checklist> GetChecklistTypesCache()
    { 
        return BlobCache.LocalMachine.GetAndFetchLatest("ChecklistAccessLevels",                                    
                                   async () =>
                                   {
                                       if (!await Tools.IsConnected()) return null;
                                       return await GetChecklistTypesRemote();
                                   },
                                 offset =>
                                 {
                                     TimeSpan elapsed = DateTimeOffset.Now - offset;
                                     return elapsed > new TimeSpan(hours: 0, minutes: 0, seconds: 30);
                                 });

    }

    public async Task<ChecklistModel> GetChecklistTypesRemote()
    {
      //do something
    }


    //calling code
    //Now this is going to possibly fire twice. Once for the cached version 
    //and then one for the version from the Func
     GetChecklistTypesCache().Subscribe(subsribedData =>
        {
            List<ChecklistModel.Checklist> checklistCollection = new 
            List<ChecklistModel.Checklist>();
            checklistCollection.Clear();
            checklistCollection.Add(subsribedData);
            checkilstModel = checklistCollection.ToObservable();
        });

Если вы хотите использовать async / await, вам просто нужно использовать части Akavache, которые возвращают только один результат

Все они взяты из примеров на странице github https://github.com/akavache/Akavache

Итак, сначала вы попытаетесь получить свою вещь из кеша

try {
    toaster = await BlobCache.LocalMachine.GetObjectAsync("ChecklistAccessLevels");
} catch (KeyNotFoundException) {

}

Если его там нет, вы бы назвали свой функционал

if(toaster == null)
   toaster = await GetChecklistTypesRemote()

Теперь вы вставите его в кеш

await BlobCache.LocalMachine.InsertObject("ChecklistAccessLevels", toaster );

Но, возможно, "GetOrFetchObject" будет работать лучше для вашей цели, так как он будет срабатывать только один раз и будет работать с задачей? Но немного сложно сформировать ответ, потому что я до сих пор не совсем понятен вариант использования. Я думаю, что чтение https://reactiveui.net/concepts было бы полезно, и как только концепции Reactive завладеют, взаимодействия станут более понятными.

GetAndFetchLatest возвращается несколько раз. Он предназначен для использования с Reactive Extensions в качестве наблюдаемой, на которую вы подписаны. Паттерн обещания / асинхронности / ожидания возвращается только один раз. Rx уже более 9 лет, и его стоит изучить - см. https://reactiveui.net/concepts

Другие вопросы по тегам