public async Task FromAsync(Stream source, bool disposeWhenDone = false, CancellationToken cancellationToken = default(CancellationToken)) { try { VerifyDisposure(); IPartitionGenerator partitioner = null; lock (Partitions) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (HasSource) { throw new Exceptions.MultipleSourceException(); } HasSource = true; partitioner = this.PartitionGenerator; } if (partitioner == null) { partitioner = PartitionGeneratorFactory.Create(); } var asyncGenerator = partitioner.GenerateAsync(source, cancellationToken); while (await asyncGenerator.MoveNext()) { var part = asyncGenerator.Current(); if (part != null) { try { PartitionEditorLock.EnterWriteLock(); this.TotalStreamLength += part.Size; this.Partitions.AddLast(part); } finally { PartitionEditorLock.ExitWriteLock(); } lock (Partitions) { var x = TCS_ReceivedNextPartition; TCS_ReceivedNextPartition = new TaskCompletionSource <long>(); x.SetResult(part.Size); } } } SourceRead = true; } catch (TaskCanceledException tce) { lock (Partitions) { TCS_ReceivedNextPartition.TrySetCanceled(tce.CancellationToken); TCS_ReceivedLastPartition.TrySetCanceled(tce.CancellationToken); } throw; } finally { if (disposeWhenDone) { source.Dispose(); } lock (Partitions) { if (!TCS_ReceivedNextPartition.Task.IsCanceled) { TCS_ReceivedNextPartition.SetResult(StreamLength); } if (!TCS_ReceivedLastPartition.Task.IsCanceled) { TCS_ReceivedLastPartition.SetResult(StreamLength); } } } }
public void From(Stream source, bool disposeWhenDone = false) { try { VerifyDisposure(); IPartitionGenerator partitioner = null; lock (Partitions) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (HasSource) { throw new Exceptions.MultipleSourceException(); } HasSource = true; partitioner = this.PartitionGenerator; } if (partitioner == null) { partitioner = PartitionGeneratorFactory.Create(); } foreach (var part in partitioner.Generate(source)) { if (part == null) { continue; } try { PartitionEditorLock.EnterWriteLock(); this.TotalStreamLength += part.Size; this.Partitions.AddLast(part); } finally { PartitionEditorLock.ExitWriteLock(); } lock (Partitions) { var x = TCS_ReceivedNextPartition; TCS_ReceivedNextPartition = new TaskCompletionSource <long>(); x.SetResult(part.Size); } } lock (Partitions) { SourceRead = true; TCS_ReceivedNextPartition.SetResult(StreamLength); TCS_ReceivedLastPartition.SetResult(StreamLength); } } finally { if (disposeWhenDone) { source.Dispose(); } } }