Xamarin.android Akavache GetAndFetchLatest从不调用fetchfunc

Xamarin.android Akavache GetAndFetchLatest从不调用fetchfunc,xamarin.android,xamarin.forms,akavache,Xamarin.android,Xamarin.forms,Akavache,和阿卡瓦什一起工作了几天。我有几个使用GetAndFetchLatest方法的方法,但是有些方法从不调用fetchFunc,并且所有函数都会随机出现这个问题 public async Task<ChecklistModel> GetChecklistTypes() { var ChecklistTypesCache = BlobCache.LocalMachine.GetAndFetchLatest("ChecklistT

和阿卡瓦什一起工作了几天。我有几个使用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
 }
公共异步任务GetChecklistTypes() { var ChecklistTypesCache= BlobCache.LocalMachine.GetAndFetchLatest(“ChecklistTypes”, ()=>GetChecklistTypesRemote(), 偏移量=> { TimeSpan appeased=DateTimeOffset.Now-offset; 返回已用时间>新时间跨度(小时:0,分钟:5,秒:0); }); ChecklistTypesCache.Subscribe(subscribedData=> { _checkilstModel=子脚本数据; }); _checkilstModel=wait ChecklistTypesCache.FirstOrDefaultAsync(); 返回_checkilstModel; } 公共异步任务GetChecklistTypesRemote() { //做点什么 } 有人面临这个问题吗?我需要做些别的事情来工作吗?如何解决这个问题

“更新代码”
公共异步任务
GetChecklistTypesCache()
{
IEnumerable checklistModel=null;
var ChecklistTypesCache=
BlobCache.LocalMachine.GetAndFetchLatest(“CheckListAccessLevel”,
()=>GetChecklistTypesRemote(),
偏移量=>
{
时间跨度经过=日期时间偏移。现在-
抵消;
返回已用时间>新时间跨度(小时数:0,
分:5秒:0);
});
ChecklistTypesCache.Subscribe(subscribedData=>
{
checklistModel=subscribeddata;
});
checklistModel=等待ChecklistTypesCache.FirstOrDefaultAsync();
返回清单模型;
}
公共异步任务GetChecklistTypesRemote()
{
//做点什么
}

GetAndFetchLatest多次返回。它被设计为和反应式扩展一起使用,作为您订阅的可观察对象。promise/async/await模式只返回一次。Rx现在已经9岁多了,非常值得学习-请参见

详细说明@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();
        });
如果它不在那里,你就给你的func打电话

if(toaster == null)
   toaster = await GetChecklistTypesRemote()
现在将其插入缓存

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

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

但也许“GetOrFetchObject”会更好地满足您的需求,因为它只会触发一次,并且可以处理一个任务?但要形成一个响应有点困难,因为我还不太清楚用例。我认为通读将是有益的,一旦反应性概念占据了更多的位置,交互将变得更有意义。

订阅和等待可能会很奇怪,因为它订阅了两次可观察对象,这是一个参考计数,因此将其作为可观察对象进行表面化并使用它可能会有所帮助。第二件事是GetAndFetchLatest将生成两个结果,一个是缓存版本,另一个是来自func的结果。我在想,如果您正在执行FirstOrDefaultAsync,可能会在执行第二个操作(func)之前取消订阅。如果要使用Wait,最好不要使用GetAndFetchLatest,而是等待Get,然后自己调用func并缓存它。GetAndFetchLatest更适合于基于观察的设计(因此不使用Wait),因为它将产生两个结果。通常,只有当您关心可观察序列的最后一个结果或可观察序列只会产生一个结果时,您才会使用wait。也许可以尝试看看我在示例项目中是如何使用它的。这里使用可观察序列的设置不同于异步/等待。。。(就像“ShaneNeuville”已经说过的那样)非常感谢Depchie和“ShaneNeuville”。将更新我问题中的代码。它似乎在工作,但希望确保代码不会被破坏。请检查并提供更多信息。因此更新仍然没有真正意义。。GetAndFetchLatest向订阅服务器提供了两条消息,您不能使用任务表示该概念,因为该任务只能生成一个结果。GetAndFetchLatest的要点是向订阅服务器提供缓存的结果,激发func,然后缓存该结果,然后也向订阅服务器提供该结果。如果要坚持等待,请不要使用GetAndFetchLatest,使用其他工具。您的用例是什么?你到底想要实现什么?如果该值已经被缓存,那么它是否仍将被发送到服务器?感谢@GeoffreyThanks提供的提示,以获得@shane的详细答案。如果我在这里返回缓存值而不是返回null,这样可以吗。如果(!wait Tools.IsConnected())返回null;GetAndFetchLatest的工作方式是,来自observable的第一个通知将是缓存的值,因此调用代码将使用该值,然后调用func,这是第二个通知。如果没有缓存的值,则只会收到来自func的一个通知,如果再次调用,则拿两个。从func返回缓存的值实际上没有任何意义
await BlobCache.LocalMachine.InsertObject("ChecklistAccessLevels", toaster );