public async Task ExecuteAsync(IDataSourceAdapter source, IDataSinkAdapter sink, ITransferStatistics statistics, CancellationToken cancellation)
        {
            Guard.NotNull("source", source);
            Guard.NotNull("sink", sink);
            Guard.NotNull("statistics", statistics);

            var writeTasks = Enumerable
                    .Range(0, sink.MaxDegreeOfParallelism)
                    .Select(i => (Task)Task.FromResult<object>(null))
                    .ToArray();

            var fatalExceptions = new List<Exception>();
            var readOutput = new ReadOutputByRef();
            IDataItem dataItem;
            while (!cancellation.IsCancellationRequested)
            {
                readOutput.Wipe();

                try
                {
                    dataItem = await source.ReadNextAsync(readOutput, cancellation);
                }
                catch (NonFatalReadException nonFatalException)
                {
                    statistics.AddError(readOutput.DataItemId, nonFatalException);
                    continue;
                }
                catch (Exception exception)
                {
                    fatalExceptions.Add(exception);
                    break;
                }

                if (dataItem == null || cancellation.IsCancellationRequested)
                    break;

                var completed = await Task.WhenAny(writeTasks);
                writeTasks[Array.IndexOf(writeTasks, completed)] =
                    TransferDataItem(sink, readOutput.DataItemId, dataItem, statistics, cancellation);
            }

            // Report completion to the sink
            try
            {
                await sink.CompleteAsync(cancellation);
            }
            catch (Exception exception)
            {
                fatalExceptions.Add(exception);
            }

            // Wait for all on-going writes to complete
            for (var index = 0; index < writeTasks.Length; ++index)
                await writeTasks[index];

            // Throw fatal exceptions, if any
            if (fatalExceptions.Any())
                throw new AggregateException(fatalExceptions);
        }
        protected async Task WriteDataAsync(IDataSinkAdapter sinkAdapter, IEnumerable<IDataItem> data)
        {
            Task[] writeTasks = Enumerable
                .Range(0, sinkAdapter.MaxDegreeOfParallelism)
                .Select(i => (Task)Task.FromResult<object>(null))
                .ToArray();

            foreach (var dataItem in data)
            {
                var completed = await Task.WhenAny(writeTasks);
                await completed;
                writeTasks[Array.IndexOf(writeTasks, completed)] =
                    sinkAdapter.WriteAsync(dataItem, CancellationToken.None);
            }

            await sinkAdapter.CompleteAsync(CancellationToken.None);

            for (var index = 0; index < writeTasks.Length; ++index)
                await writeTasks[index];
        }
        protected async Task WriteDataAsync(IDataSinkAdapter sinkAdapter, IEnumerable <IDataItem> data)
        {
            Task[] writeTasks = Enumerable
                                .Range(0, sinkAdapter.MaxDegreeOfParallelism)
                                .Select(i => (Task)Task.FromResult <object>(null))
                                .ToArray();

            foreach (var dataItem in data)
            {
                var completed = await Task.WhenAny(writeTasks);

                await completed;
                writeTasks[Array.IndexOf(writeTasks, completed)] =
                    sinkAdapter.WriteAsync(dataItem, CancellationToken.None);
            }

            await sinkAdapter.CompleteAsync(CancellationToken.None);

            for (var index = 0; index < writeTasks.Length; ++index)
            {
                await writeTasks[index];
            }
        }
コード例 #4
0
        private static async Task TransferData(IDataSourceAdapter source, IDataSinkAdapter sink, ITransferStatistics statistics, CancellationToken cancellation)
        {
            var writeTasks = Enumerable
                             .Range(0, sink.MaxDegreeOfParallelism)
                             .Select(i => (Task)Task.FromResult <object>(null))
                             .ToArray();

            var       fatalExceptions = new List <Exception>();
            var       readOutput      = new ReadOutputByRef();
            IDataItem dataItem;

            while (!cancellation.IsCancellationRequested)
            {
                readOutput.Wipe();

                try
                {
                    dataItem = await source.ReadNextAsync(readOutput, cancellation);
                }
                catch (NonFatalReadException nonFatalException)
                {
                    statistics.AddError(readOutput.DataItemId, nonFatalException);
                    continue;
                }
                catch (Exception exception)
                {
                    fatalExceptions.Add(exception);
                    break;
                }

                if (dataItem == null || cancellation.IsCancellationRequested)
                {
                    break;
                }

                var completed = await Task.WhenAny(writeTasks);

                writeTasks[Array.IndexOf(writeTasks, completed)] =
                    TransferDataItem(sink, readOutput.DataItemId, dataItem, statistics, cancellation);
            }

            // Report completion to the sink
            try
            {
                await sink.CompleteAsync(cancellation);
            }
            catch (Exception exception)
            {
                fatalExceptions.Add(exception);
            }

            // Wait for all on-going writes to complete
            for (var index = 0; index < writeTasks.Length; ++index)
            {
                await writeTasks[index];
            }

            // Throw fatal exceptions, if any
            if (fatalExceptions.Any())
            {
                throw new AggregateException(fatalExceptions);
            }
        }