创建任务链

Create a chain of tasks

我正在编写一个后台服务,它可以在我的 Web 服务器处于 运行 时提取有关产品的历史数据。我只能以特定速率发出请求,因此,出于这个原因,我需要创建一个 executionQueue:

创建这个任务列表很冗长,我不明白为什么要这样。 也许我只是把事情复杂化了:

public List<Task<Task<List<Candle>>>> BuildHistoricalDataTaskList(CryptoInfoContext context, string productId, DateTime totalStartDate, DateTime totalEndDate, Granularity[] granularities, int maxResults = 300)
{
    var product = this.GetProductFromId(context, productId);
    var executionQueue = new List<Task<Task<List<Candle>>>>();
    foreach (var granularity in granularities)
    {
        var granularityMinutes = (int)granularity;
        var startDate = totalStartDate;
        var maxRangeMinutes = maxResults * granularityMinutes;

        while (startDate <= totalEndDate)
        {
            var endDate = startDate.AddMinutes(maxRangeMinutes);
            var task = new Task<Task<List<Candle>>>(() =>
            {
                return ProcessHistoricalDataAsync(productId, startDate, endDate, granularity);
            });

            executionQueue.Add(task);
            startDate = endDate;
        }
    }

    return executionQueue;
}

我的 return 类型似乎有点冗长,有什么方法可以压缩这些任务吗?

也许 observable 是可行的方法,但我不确定该怎么做。

看起来中间的 Task 只是表现为延迟执行关闭。因此,您可以将其替换为 Func<Task<List<Candle>>> 并获得相同的效果。这没有任何帮助,但它减少了 Task<Task<...>>.

引入的混乱

我假设这之外是处理队列的东西,所以你能把它精简成 IEnumerable<Func<Task<List<Candle>>>> 吗?

例如

public IEnumerable<Func<Task<List<Candle>>>> BuildHistoricalDataTaskList(CryptoInfoContext context, string productId, DateTime totalStartDate, DateTime totalEndDate, Granularity[] granularities, int maxResults = 300)
{
    var product = this.GetProductFromId(context, productId);
    foreach (var granularity in granularities)
    {
        var granularityMinutes = (int)granularity;
        var startDate = totalStartDate;
        var maxRangeMinutes = maxResults * granularityMinutes;

        while (startDate <= totalEndDate)
        {
            var endDate = startDate.AddMinutes(maxRangeMinutes);
            yield return () =>
            {
                return ProcessHistoricalDataAsync(productId, startDate, endDate, granularity);
            };
            
            startDate = endDate;
        }
    }
}

从签名的角度来看也好不了多少。但它稍微小一些。而且你根本没有使用 product,这可能会让你付出一些代价。