public static async Task Load(IDictionary <string, object> dataExprsAndCookies, DateTime StartDate, DateTime EndDate, long[] ids, string idParamName, string contextInitializationScript, OnDataLoading onDataLoading, Action <float> onProgress, int maxPartSize, System.Threading.CancellationToken ct) { bool timeRange = StartDate < EndDate; bool withAggr = ids.Length > 1; int nTotalPartsToLoad = 0; int nPartsLoaded = 0; AsyncFn fProgress = async(aec, args) => { if (!ct.IsCancellationRequested) { var info = (LoadingInfo)await OPs.ConstValueOf(aec, args[0]); var value = await OPs.ConstValueOf(aec, args[1]); var data = value as IList; if (data != null) { var aggData = await info.Aggregate(aec, data); onDataLoading(info.dataExpr, info.cookie, (IList)aggData); Interlocked.Increment(ref nPartsLoaded); } else // calc n { int n = Convert.ToInt32(value); Interlocked.Add(ref nTotalPartsToLoad, n); } if (onProgress != null) { onProgress(100f * nPartsLoaded / nTotalPartsToLoad); } } return(string.Empty); }; // initialize code generator context var defs = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase); defs.Add(idParamName, ids); defs.Add("PROGRESS", new FuncDef(fProgress, 2, "PROGRESS")); if (timeRange) { defs.Add(nameof(ValueInfo.A_TIME__XT), StartDate.ToOADate()); defs.Add(nameof(ValueInfo.B_TIME__XT), EndDate.ToOADate()); } else { defs.Add(nameof(ValueInfo.At_TIME__XT), StartDate.ToOADate()); } var rootCtx = new Generator.Ctx(defs, CoreFuncDefs().GetFuncs); Generator.Generate(Parser.ParseToExpr(contextInitializationScript), rootCtx); rootCtx.UseFuncs(new FuncDefs().AddFrom(withAggr ? typeof(FuncDefs_Aggr) : typeof(FuncDefs_NoAggr)).GetFuncs); var infos = new List <LoadingInfo>(dataExprsAndCookies.Count); var tasks = new List <Task>(); foreach (var pair in dataExprsAndCookies) { infos.Add(new LoadingInfo(pair.Key, pair.Value, rootCtx)); } var loadingExpr = Parser.ParseToExpr(@"( PartsOfLimitedSize(" + idParamName + " ," + maxPartSize.ToString() + @") ..let(parts) ,let(n,COLUMNS(parts)) .. PROGRESS(" + sLoadingInfo + @"), ,_ParFor( let(i,0), i<n, ( let(" + idParamName + @", parts[i]) ,FindSolutionExpr({}, " + sUsedParamsDict + @".Keys()) . ExprToExecutable() . AtNdx(0) .. PROGRESS(" + sLoadingInfo + @") ,let(i, i+1) ) ) )"); var rootAec = new AsyncExprRootCtx(rootCtx.name2ndx, rootCtx.values, OPs.GlobalMaxParallelismSemaphore); foreach (var info in infos) { tasks.Add(Task.Factory.StartNew(() => info.LoadData(rootAec, loadingExpr, ct)).Unwrap()); } await TaskEx.WhenAll(tasks); }