Beispiel #1
0
        public async Task Complete()
        {
            lock (mLockObject)
            {
                if (mComplete)
                {
                    throw new InvalidOperationException();
                }

                mComplete = true;
                Monitor.PulseAll(mLockObject);

                while (!mCompleteAck)
                {
                    Monitor.Wait(mLockObject);
                }
            }

#if NET_4_6_2
            // This will probably deadlock up to .NET 4.6.1 and might be fixed in .NET 4.6.2
            // The cause is that Task.WhenAll does not respect TaskCreationOptions.RunContinuationsAsynchronously
            await Task.WhenAll(mStorage.Select(x => x.GetCompletionTask())).ConfigureAwait(false);
#else
            foreach (var stream in mStorage)
            {
                await stream.GetCompletionTask().ConfigureAwait(false);
            }
#endif

            int totalInputCount  = 0;
            var firstInputOffset = new int[mEncoders.Length];
            for (int i = 0; i < mEncoders.Length; i++)
            {
                firstInputOffset[i] = totalInputCount;
                totalInputCount    += mDefinition.GetEncoder(i).InputCount;
            }

            var decoders = ImmutableArray.CreateBuilder <DecoderMetadata>(mEncoders.Length);
            for (int i = 0; i < mEncoders.Length; i++)
            {
                var encoder     = mDefinition.GetEncoder(i);
                var settings    = encoder.Settings;
                var decoderType = settings.GetDecoderType();

                var decoderInputCount = decoderType.GetInputCount();
                var decoderInputs     = ImmutableArray.CreateBuilder <DecoderInputMetadata>(decoderInputCount);
                for (int j = 0; j < decoderInputCount; j++)
                {
                    var encoderOutput = encoder.GetOutput(j).Target;
                    if (encoderOutput.IsStorage)
                    {
                        decoderInputs.Add(new DecoderInputMetadata(null, encoderOutput.Index));
                    }
                    else
                    {
                        decoderInputs.Add(new DecoderInputMetadata(encoderOutput.Node.Index, encoderOutput.Index));
                    }
                }

                var decoderOutputCount = decoderType.GetOutputCount();
                var decoderOutputs     = ImmutableArray.CreateBuilder <DecoderOutputMetadata>(decoderOutputCount);
                for (int j = 0; j < decoderOutputCount; j++)
                {
                    var encoderInput = encoder.GetInput(j).Source;
                    if (encoderInput.IsContent)
                    {
                        System.Diagnostics.Debug.Assert(mConnections[firstInputOffset[i] + j] == null);
                        decoderOutputs.Add(new DecoderOutputMetadata(mInput.GetFinalLength()));
                    }
                    else
                    {
                        decoderOutputs.Add(new DecoderOutputMetadata(mConnections[firstInputOffset[i] + j].GetFinalLength()));
                    }
                }

                decoders.Add(new DecoderMetadata(decoderType, settings.SerializeSettings(), decoderInputs.MoveToImmutable(), decoderOutputs.MoveToImmutable()));
            }

            var inputSource = mDefinition.GetContentSource().Target;
            var definition  = new ArchiveDecoderSection(
                decoders.MoveToImmutable(),
                new DecoderInputMetadata(inputSource.Node.Index, inputSource.Index),
                mInput.GetFinalLength(),
                mInput.GetFinalChecksum(),
                mContent.ToImmutable());

            mWriter.CompleteEncoderSession(this, mSection, definition, mStorage);
        }