public async Task <IEnumerable <Item> > EnqueueItems(List <int> ids) { var stopwatch = Stopwatch.StartNew(); var(items, misses) = _cache.GetCachedItems(ids); var newItems = new List <Item>(); var buffer = new BufferBlock <int>(); var downloader = new ActionBlock <int>(async id => { var action = await _client.GetStringAsync($"item/{id}.json"); // handle data here var storyItem = JsonConvert.DeserializeObject <Item>(action); newItems.Add(storyItem); var msg = new NewsItemMessage(this, storyItem); _messenger.Publish(msg); }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }); // notify TPL Dataflow to send messages from buffer to loader buffer.LinkTo(downloader, new DataflowLinkOptions { PropagateCompletion = true }); foreach (var itemId in misses) { await buffer.SendAsync(itemId); } // queue is done buffer.Complete(); // now it's safe to wait for completion of the downloader await downloader.Completion; var itemList = items.ToList(); foreach (var item in itemList) { var msg = new NewsItemMessage(this, item); _messenger.Publish(msg); } _cache.AddItemsToCache(newItems); stopwatch.Stop(); var ms = stopwatch.ElapsedMilliseconds; Debug.WriteLine("Queue completed in {0} ms", ms); return(itemList); }
private void OnItemReceived(NewsItemMessage msg) { var id = msg.Data.Id; if (!_storyLookup.TryGetValue(id, out var wrapper)) { return; } wrapper.Fill(msg.Data); _storyLookup.Remove(id); }
public IEnumerable <Item> EnqueueItems(List <int> ids) { var stopwatch = Stopwatch.StartNew(); var(items, misses) = _cache.GetCachedItems(ids); var newItems = new List <Item>(); var tasks = misses.Select(id => _client.GetStringAsync($"item/{id}.json") .ContinueWith(task => { if (task.Status != TaskStatus.RanToCompletion) { return; } var storyItem = JsonConvert.DeserializeObject <Item>(task.Result); newItems.Add(storyItem); var msg = new NewsItemMessage(this, storyItem); _messenger.Publish(msg); })); var itemList = items.ToList(); foreach (var item in itemList) { var msg = new NewsItemMessage(this, item); _messenger.Publish(msg); } Task.WhenAll(tasks).ContinueWith(x => { _cache.AddItemsToCache(newItems); stopwatch.Stop(); var ms = stopwatch.ElapsedMilliseconds; Debug.WriteLine("Queue completed in {0} ms", ms); }); return(itemList); }