3

过去几天与 Akavache 合作。我有几种使用 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
    }
4

2 回答 2

4

GetAndFetchLatest 多次返回。它被设计为与 Reactive Extensions 一起使用,作为您订阅的 observable。promise/async/await 模式只返回一次。Rx 现在已经 9 岁多了,非常值得学习 - 请参阅https://reactiveui.net/concepts

于 2017-06-13T23:27:03.257 回答
3

因此,要详细说明@Geoffrey Huntley 所说的内容,很难做出回应,因为您的做法(即使在要点中)“被动地”并没有真正的意义。如果您要使用 promise/async/await 模式,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) {

}

如果它不在那里,那么你会打电话给你的 func

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

现在您将其插入缓存

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

但也许“GetOrFetchObject”会更好地满足您的目的,因为它只会触发一次并且可以处理任务?但是很难做出响应,因为我仍然不太清楚用例。我认为阅读https://reactiveui.net/concepts会很有用,一旦 Reactive 概念更深入人心,交互就会更有意义。

于 2017-06-17T21:36:52.410 回答