Пример #1
0
            /// <summary>Notifies the stream that no more data will be written.</summary>
            internal void SignalComplete(Exception error = null, bool forceCancel = false)
            {
                lock (_lockObject)
                {
                    VerifyInvariants();

                    // If we already completed, nothing more to do
                    if (_completed != null)
                    {
                        EventSourceTrace("Already completed");
                        return;
                    }

                    // Mark ourselves as being completed
                    EventSourceTrace("Marking as complete");
                    _completed = error ?? s_completionSentinel;

                    // If the request wasn't already completed, and if requested, send a cancellation
                    // request to ensure that the connection gets cleaned up.  This is only necessary
                    // to do if this method is being called for a reason other than the request/response
                    // completing naturally, e.g. if the response stream is being disposed of before
                    // all of the response has been downloaded.
                    if (forceCancel)
                    {
                        EventSourceTrace("Completing the response stream prematurely.");
                        _easy._associatedMultiAgent.RequestCancel(_easy);
                    }

                    // If there's a pending read request, complete it, either with 0 bytes for success
                    // or with the exception/CancellationToken for failure.
                    ReadState pendingRead = _pendingReadRequest;
                    if (pendingRead != null)
                    {
                        if (_completed == s_completionSentinel)
                        {
                            EventSourceTrace("Completing pending read with 0 bytes");
                            pendingRead.TrySetResult(0);
                        }
                        else
                        {
                            EventSourceTrace("Failing pending read task with error: {0}", _completed);
                            OperationCanceledException oce = _completed as OperationCanceledException;
                            if (oce != null)
                            {
                                pendingRead.TrySetCanceled(oce.CancellationToken);
                            }
                            else
                            {
                                pendingRead.TrySetException(MapToReadWriteIOException(_completed, isRead: true));
                            }
                        }

                        ClearPendingReadRequest();
                    }
                }
            }