/*public Task<IResultChunk> GetNextChunkAsync()
         * {
         *  return _downloadTasks.IsCompleted ? Task.FromResult<SFResultChunk>(null) : _downloadTasks.Take();
         * }*/

        public Task <IResultChunk> GetNextChunkAsync()
        {
            logger.Info($"NextChunkToConsume: {nextChunkToConsumeIndex}, NextChunkToDownload: {nextChunkToDownloadIndex}");
            if (nextChunkToConsumeIndex < chunkInfos.Count)
            {
                Task <IResultChunk> chunk = taskQueues[nextChunkToConsumeIndex % prefetchSlot];

                if (nextChunkToDownloadIndex < chunkInfos.Count && nextChunkToConsumeIndex > 0)
                {
                    SFReusableChunk reusableChunk = chunkDatas[nextChunkToDownloadIndex % prefetchSlot];
                    reusableChunk.Reset(chunkInfos[nextChunkToDownloadIndex], nextChunkToDownloadIndex);

                    taskQueues[nextChunkToDownloadIndex % prefetchSlot] = DownloadChunkAsync(new DownloadContextV3()
                    {
                        chunk             = reusableChunk,
                        qrmk              = this.qrmk,
                        chunkHeaders      = this.chunkHeaders,
                        cancellationToken = externalCancellationToken
                    });
                    nextChunkToDownloadIndex++;
                }

                nextChunkToConsumeIndex++;
                return(chunk);
            }
            else
            {
                return(Task.FromResult <IResultChunk>(null));
            }
        }
        public SFBlockingChunkDownloaderV3(int colCount,
                                           List <ExecResponseChunk> chunkInfos, string qrmk,
                                           Dictionary <string, string> chunkHeaders,
                                           CancellationToken cancellationToken,
                                           SFBaseResultSet ResultSet)
        {
            this.qrmk                     = qrmk;
            this.chunkHeaders             = chunkHeaders;
            this.nextChunkToDownloadIndex = 0;
            this.ResultSet                = ResultSet;
            this.prefetchSlot             = Math.Min(chunkInfos.Count, GetPrefetchThreads(ResultSet));
            this.chunkInfos               = chunkInfos;
            this.nextChunkToConsumeIndex  = 0;
            this.taskQueues               = new List <Task <IResultChunk> >();
            externalCancellationToken     = cancellationToken;

            for (int i = 0; i < prefetchSlot; i++)
            {
                SFReusableChunk reusableChunk = new SFReusableChunk(colCount);
                reusableChunk.Reset(chunkInfos[nextChunkToDownloadIndex], nextChunkToDownloadIndex);
                chunkDatas.Add(reusableChunk);

                taskQueues.Add(DownloadChunkAsync(new DownloadContextV3()
                {
                    chunk             = reusableChunk,
                    qrmk              = this.qrmk,
                    chunkHeaders      = this.chunkHeaders,
                    cancellationToken = this.externalCancellationToken
                }));

                nextChunkToDownloadIndex++;
            }
        }