private async Task BeginRefreshAsync(int startAt, bool shouldAwait, CancellationToken cancelToken) { IList <ItemKey> keysToDownload = m_data.Keys.CollectKeysNeedingDownload(startAt, ReadAheadChunkSize); if (keysToDownload.IsNullOrEmpty()) { return; } // // Refresh happens in the background // This will return as soon as the task is launched // PendingGetCompletionDelegate completionCallback = null; if (!shouldAwait) { completionCallback = PendingGetCompletion; // Callback => download items in background } PendingGetResult result = await Store.RefreshAsyncImpl( keysToDownload, m_data.TypeVersions, completionCallback, cancelToken); if (result == null) { return; // NO pending work } PendingGetCompletion(this, result); }
/// <summary> /// Triggers a FORCED refresh in the background and returns as soon as it can /// When the background fetch completes, invokes the callback /// </summary> public IAsyncAction DownloadAsync( IList <ItemKey> keys, IList <string> typeVersions, PendingGetCompletionDelegate callback) { if (callback == null) { throw new ArgumentNullException("callback"); } return(AsyncInfo.Run(async cancelToken => { await DownloadAsyncImpl(keys, typeVersions, callback, cancelToken); })); }
/// <summary> /// Returns a list of items such that: /// - If an item matching the equivalent key is available locally, returns it /// - ELSE returns a NULL item at the ordinal matching the key - indicating that the item is PENDING /// - Issues a background get for the pending items, and notifies you (callback) when done /// This technique is useful for making responsive UIs. /// - User can view locally available items quickly /// - Pending items are shown as 'loading' and updated as they become available /// </summary> /// <param name="keys">keys to retrieve</param> /// <param name="typeVersions"></param> /// <returns>List with COUNT == keys.Count. If an item was not found locally, the equivalent item in the list is NULL</returns> public IAsyncOperation<IList<IItemDataTyped>> GetAsync( IList<ItemKey> keys, IList<string> typeVersions, PendingGetCompletionDelegate callback) { if (keys == null) { throw new ArgumentNullException("keys"); } return AsyncInfo.Run(cancelToken => GetAsyncImpl(keys, typeVersions, callback, cancelToken)); }
public IAsyncOperation <IList <RecordItem> > GetItemsAsync( IList <ItemKey> keys, IList <string> typeVersions, PendingGetCompletionDelegate callback) { if (keys == null) { throw new ArgumentNullException("keys"); } return(AsyncInfo.Run(async cancelToken => await GetItemsAsyncImpl(keys, typeVersions, callback, cancelToken))); }
private void NotifyPendingGetComplete(PendingGetCompletionDelegate callback, PendingGetResult result) { if (callback != null) { try { callback(this, result); } catch { } } }
internal async Task <IList <RecordItem> > GetItemsAsyncImpl(IList <ItemKey> keys, IList <string> typeVersions, PendingGetCompletionDelegate callback, CancellationToken cancelToken) { // // true: include null items - i.e. items not found in the local store // IList <RecordItem> foundItems = await m_localStore.GetItemsAsyncImpl(keys, true); // // Trigger a download of items that are not available yet... // IList <ItemKey> pendingKeys = CollectKeysNeedingDownload(keys, typeVersions, foundItems); if (pendingKeys.IsNullOrEmpty()) { return(foundItems); } PendingGetResult pendingResult = await DownloadAsyncImpl(pendingKeys, typeVersions, callback, cancelToken); if (pendingResult == null) { return(foundItems); } // // Load fresh items // if (pendingResult.HasKeysFound) { await LoadNewItems(foundItems, keys, pendingResult.KeysFound); } return(foundItems); }
internal async Task<PendingGetResult> DownloadItems(IList<ItemKey> keys, IList<string> typeVersions, PendingGetCompletionDelegate callback, CancellationToken cancelToken) { var result = new PendingGetResult(); try { result.KeysRequested = keys; ItemQuery query = this.CreateRefreshQueryForKeys(keys, typeVersions); IList<RecordItem> items = await m_remoteStore.GetAllItemsAsync(query); await this.PersistDownloadedItemsAsync(items); result.KeysFound = ( from item in items select item.Key ).ToArray(); } catch (Exception ex) { result.Exception = ex; } NotifyPendingGetComplete(callback, result); return result; }
private async Task<PendingGetResult> DownloadItems( IList<ItemKey> keys, IList<string> typeVersions, PendingGetCompletionDelegate callback, CancellationToken cancelToken) { var result = new PendingGetResult(); try { result.KeysRequested = keys; ItemQuery query = ItemQuery.QueryForKeys(keys); query.View.SetSections(SectionsToFetch); if (typeVersions != null && typeVersions.Count > 0) { query.View.TypeVersions.AddRange(typeVersions); } IList<RecordItem> items = await m_record.GetAllItemsAsync(query); await m_itemStore.PutItemsAsyncImpl(items); result.KeysFound = ( from item in items select item.Key ).ToArray(); } catch (Exception ex) { result.Exception = ex; } NotifyPendingGetComplete(callback, result); return result; }
internal async Task<PendingGetResult> RefreshAsyncImpl( IList<ItemKey> keys, IList<string> typeVersions, PendingGetCompletionDelegate callback, CancellationToken cancelToken) { IList<ItemKey> pendingKeys = await CollectKeysNotInLocalStore(keys, typeVersions); if (pendingKeys.IsNullOrEmpty()) { return null; // No pending work } return await DownloadAsyncImpl(pendingKeys, typeVersions, callback, cancelToken); }
internal async Task<PendingGetResult> DownloadAsyncImpl( IList<ItemKey> keys, IList<string> typeVersions, PendingGetCompletionDelegate callback, CancellationToken cancelToken) { if (callback != null) { // // Run the download in the background. // Return what we have right away, and notify caller when pending items arrive // Task task = DownloadItems(keys, typeVersions, callback, cancelToken); return null; } // // Wait for download to complete... // PendingGetResult result = await DownloadItems(keys, typeVersions, callback, cancelToken); result.EnsureSuccess(); return result; }
private async Task<IList<RecordItem>> GetItemsAsyncImpl( IList<ItemKey> keys, IList<string> typeVersions, PendingGetCompletionDelegate callback, CancellationToken cancelToken) { // // true: include null items - i.e. items not found in the local store // IList<RecordItem> foundItems = await Local.GetItemsAsyncImpl(keys, true); // // Trigger a download of items that are not available yet... // IList<ItemKey> pendingKeys = CollectKeysNeedingDownload(keys, typeVersions, foundItems); if (pendingKeys.IsNullOrEmpty()) { return foundItems; } PendingGetResult pendingResult = await DownloadAsyncImpl(pendingKeys, typeVersions, callback, cancelToken); if (pendingResult == null) { return foundItems; } // // Load fresh items // if (pendingResult.HasKeysFound) { await LoadNewItems(foundItems, keys, pendingResult.KeysFound); } return foundItems; }
internal async Task<IList<IItemDataTyped>> GetAsyncImpl( IList<ItemKey> keys, IList<string> typeVersions, PendingGetCompletionDelegate callback, CancellationToken cancelToken) { IList<RecordItem> items = await GetItemsAsyncImpl(keys, typeVersions, callback, cancelToken); if (items != null) { return ( from item in items select (item != null ? item.TypedData : null) ).ToArray(); } return null; }
/// <summary> /// Triggers a FORCED refresh in the background and returns as soon as it can /// When the background fetch completes, invokes the callback /// </summary> public IAsyncAction DownloadAsync( IList<ItemKey> keys, IList<string> typeVersions, PendingGetCompletionDelegate callback) { if (callback == null) { throw new ArgumentNullException("callback"); } return AsyncInfo.Run(async cancelToken => { await DownloadAsyncImpl(keys, typeVersions, callback, cancelToken); }); }
internal async Task <PendingGetResult> DownloadItems(IList <ItemKey> keys, IList <string> typeVersions, PendingGetCompletionDelegate callback, CancellationToken cancelToken) { var result = new PendingGetResult(); try { result.KeysRequested = keys; ItemQuery query = this.CreateRefreshQueryForKeys(keys, typeVersions); IList <RecordItem> items = await m_remoteStore.GetAllItemsAsync(query); await this.PersistDownloadedItemsAsync(items); result.KeysFound = ( from item in items select item.Key ).ToArray(); } catch (Exception ex) { result.Exception = ex; } NotifyPendingGetComplete(callback, result); return(result); }
internal async Task <PendingGetResult> RefreshAsyncImpl(IList <ItemKey> keys, IList <string> typeVersions, PendingGetCompletionDelegate callback, CancellationToken cancelToken) { IList <ItemKey> pendingKeys = await CollectKeysNotInLocalStore(keys, typeVersions); if (pendingKeys.IsNullOrEmpty()) { return(null); // No pending work } System.Diagnostics.Debug.WriteLine("Downloading {0} items", keys.Count); return(await DownloadAsyncImpl(pendingKeys, typeVersions, callback, cancelToken)); }
internal async Task <PendingGetResult> DownloadAsyncImpl(IList <ItemKey> keys, IList <string> typeVersions, PendingGetCompletionDelegate callback, CancellationToken cancelToken) { if (callback != null) { // // Run the download in the background. // Return what we have right away, and notify caller when pending items arrive // Task task = DownloadItems(keys, typeVersions, callback, cancelToken); return(null); } // // Wait for download to complete... // PendingGetResult result = await DownloadItems(keys, typeVersions, callback, cancelToken); result.EnsureSuccess(); return(result); }
internal async Task <IList <IItemDataTyped> > GetAsyncImpl(IList <ItemKey> keys, IList <string> typeVersions, PendingGetCompletionDelegate callback, CancellationToken cancelToken) { IList <RecordItem> items = await GetItemsAsyncImpl(keys, typeVersions, callback, cancelToken); if (items != null) { return(( from item in items select(item != null ? item.TypedData : null) ).ToArray()); } return(null); }