private async Task UpdateDayTradesAsync(DateTime dt) { try { var hSrv = StaticServiceFactory.Create <IHistoryService>(); var blSrv = StaticServiceFactory.Create <IBestLimitService>(); var tSrv = StaticServiceFactory.Create <ITradeService>(); var shSrv = StaticServiceFactory.Create <IShareHolderChangeService>(); var cpSrv = StaticServiceFactory.Create <IClosingPriceService>(); var codes = Online.Data.Values.Select(x => x.inscode); OnOperationStart?.Invoke(this, codes.Count() * 5); var extractDayDetailsBlock = new TransformBlock <long, DayTradeDetails>( async insCode => { var r = await Online.ExtractDayDetailsAsync(insCode, dt); OnOperationStep?.Invoke(this, EventArgs.Empty); return(r); }, new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 15 }); var writeBestLimits = new TransformBlock <DayTradeDetails, DayTradeDetails>(async c => { try { if (c != null && c.BestLimits.Count > 0 && !await blSrv.GetDefaultQuery() .Where(x => x.InsCode == c.InsCode && x.DateTime == dt) .AnyAsync()) { await blSrv.Repository.BulkInsertAsync(c.BestLimits); _logger.InfoFormat("write {0} Best Limits to database.", c.BestLimits.Count); } } catch (Exception) { throw; } OnOperationStep?.Invoke(this, EventArgs.Empty); return(c); }); var writeTrades = new TransformBlock <DayTradeDetails, DayTradeDetails>(async c => { try { if (c != null && c.Trades.Count > 0 && !await tSrv.GetDefaultQuery() .Where(x => x.InsCode == c.InsCode && x.DateTime == dt) .AnyAsync()) { _logger.InfoFormat("write {0} Trades to database.", c.Trades.Count); } } catch (Exception) { throw; } OnOperationStep?.Invoke(this, EventArgs.Empty); return(c); }); var writeClosingPrices = new TransformBlock <DayTradeDetails, DayTradeDetails>(async c => { var tomorow = dt.AddDays(1); if (c != null && c.ClosingPriceData.Count > 0 && !await cpSrv.GetDefaultQuery() .Where(x => x.InsCode == c.InsCode && x.DateTime >= dt && x.DateTime < tomorow) .AnyAsync()) { try { await cpSrv.Repository.BulkInsertAsync(c.ClosingPriceData); } catch (Exception) { throw; } _logger.InfoFormat("write {0} Closing Price to database.", c.ClosingPriceData.Count); } OnOperationStep?.Invoke(this, EventArgs.Empty); return(c); }); var writeShareHolderStates = new ActionBlock <DayTradeDetails>(async c => { try { if (c != null && c.ShareHolderStates.Count > 0 && !await shSrv.GetDefaultQuery() .Where(x => x.InsCode == c.InsCode && x.DateTime == dt) .AnyAsync()) { await shSrv.Repository.BulkInsertAsync(c.ShareHolderStates); _logger.InfoFormat("write {0} Share Holder States to database.", c.ShareHolderStates.Count); } hSrv.Repository.BulkUpdate(x => x.InsCode == c.InsCode && x.Date == c.DayDate, x => new History { HasDetails = true }); } catch (Exception) { throw; } OnOperationStep?.Invoke(this, EventArgs.Empty); }); extractDayDetailsBlock.LinkTo(writeBestLimits, new DataflowLinkOptions() { PropagateCompletion = true }); writeBestLimits.LinkTo(writeClosingPrices, new DataflowLinkOptions() { PropagateCompletion = true }); writeClosingPrices.LinkTo(writeTrades, new DataflowLinkOptions() { PropagateCompletion = true }); writeTrades.LinkTo(writeShareHolderStates, new DataflowLinkOptions() { PropagateCompletion = true }); foreach (var code in codes) { extractDayDetailsBlock.Post(code); } extractDayDetailsBlock.Complete(); await Task.WhenAll(writeShareHolderStates.Completion, writeTrades.Completion, writeClosingPrices.Completion, writeBestLimits.Completion, extractDayDetailsBlock.Completion); OnOperationCompleted?.Invoke(this, EventArgs.Empty); } catch (Exception exception) { _logger.Error("UpdateDayTradesAsync", exception); OnOperationBreak?.Invoke(this, exception); } }