예제 #1
0
        private void ProcessEndOfResultsWorker(
            CimOperationCallbackProcessingContext callbackProcessingContext,
            CimOperation cimOperation,
            Exception exception)
        {
            if (exception == null)
            {
                this.OnCompletedInternal(callbackProcessingContext);
            }
            else
            {
                CancellationMode cancellationMode = cimOperation.CancellationMode;
                switch (cancellationMode)
                {
                case CancellationMode.NoCancellationOccured:
                case CancellationMode.IgnoreCancellationRequests:
                    this.OnErrorInternal(callbackProcessingContext, exception);
                    break;

                case CancellationMode.ThrowOperationCancelledException:
                    this.OnErrorInternal(callbackProcessingContext, new OperationCanceledException(exception.Message, exception));
                    break;

                case CancellationMode.SilentlyStopProducingResults:
                    break;

                default:
                    Debug.Assert(false, "Unrecognized CancellationMode");
                    break;
                }
            }
        }
예제 #2
0
 internal void IgnoreSubsequentCancellationRequests()
 {
     lock (this._cancellationModeLock)
     {
         if (this._cancellationMode == CancellationMode.NoCancellationOccured)
         {
             this._cancellationMode = CancellationMode.IgnoreCancellationRequests;
         }
     }
 }
        private static void Cancel(CancellationMode mode, HttpClient client, CancellationTokenSource cts)
        {
            if ((mode & CancellationMode.Token) != 0)
            {
                cts?.Cancel();
            }

            if ((mode & CancellationMode.CancelPendingRequests) != 0)
            {
                client?.CancelPendingRequests();
            }

            if ((mode & CancellationMode.DisposeHttpClient) != 0)
            {
                client?.Dispose();
            }
        }
예제 #4
0
        internal void Cancel(CancellationMode cancellationMode)
        {
            Debug.Assert(cancellationMode != CancellationMode.NoCancellationOccured, "Caller should verify the right cancellation mode is used");
            Debug.Assert(cancellationMode != CancellationMode.IgnoreCancellationRequests, "Caller should verify the right cancellation mode is used");
            lock (this._cancellationModeLock)
            {
                if (this._cancellationMode == CancellationMode.IgnoreCancellationRequests)
                {
                    return;
                }
                this._cancellationMode = cancellationMode;
            }

            MI_Result result = this._handle.Cancel(MI_CancellationReason.MI_REASON_NONE);

            CimException.ThrowIfMiResultFailure(result);

            this.Cancelled.SafeInvoke(this, EventArgs.Empty);
        }
예제 #5
0
        public static Task StartWithCancellation(Action action, CancellationMode mode = CancellationMode.AmbientOrNew)
        {
            CancellationToken       token;
            CancellationTokenSource source;

            CreateToken(mode, out source, out token);

            Action a = () =>
            {
                _cancellation = token;
                try
                {
                    action();
                }
                finally
                {
                    _cancellation = CancellationToken.None;
                }
            };

            return(Task.Factory.StartNew(a, token).AddCancellationTokenSource(source));
        }
        private void ProcessEndOfResultsWorker(OperationCallbackProcessingContext callbackProcessingContext, CimOperation cimOperation, Exception exception)
        {
            if (exception != null)
            {
                CancellationMode cancellationMode  = cimOperation.CancellationMode;
                CancellationMode cancellationMode1 = cancellationMode;
                switch (cancellationMode1)
                {
                case CancellationMode.NoCancellationOccured:
                case CancellationMode.IgnoreCancellationRequests:
                {
                    this.OnErrorInternal(callbackProcessingContext, exception);
                    return;
                }

                case CancellationMode.ThrowOperationCancelledException:
                {
                    this.OnErrorInternal(callbackProcessingContext, new OperationCanceledException(exception.Message, exception));
                    return;
                }

                case CancellationMode.SilentlyStopProducingResults:
                {
                    return;
                }

                default:
                {
                    return;
                }
                }
            }
            else
            {
                this.OnCompletedInternal(callbackProcessingContext);
                return;
            }
        }
예제 #7
0
        private static void CreateToken(CancellationMode mode, out CancellationTokenSource source, out CancellationToken token)
        {
            source = default(CancellationTokenSource);
            token  = default(CancellationToken);

            switch (mode)
            {
            case CancellationMode.RequireAmbient:
                if (!_cancellation.CanBeCanceled)
                {
                    throw new InvalidOperationException("Ambient cancellation token cannot be found.");
                }

                token = _cancellation;
                break;

            case CancellationMode.RequireNew:
                source = new CancellationTokenSource();
                token  = source.Token;
                break;

            case CancellationMode.AmbientAndNew:
                if (!_cancellation.CanBeCanceled)
                {
                    throw new InvalidOperationException("Ambient cancellation token cannot be found.");
                }
                source = new CancellationTokenSource();
                token  = CancellationTokenSource.CreateLinkedTokenSource(source.Token, _cancellation).Token;
                break;

            case CancellationMode.AmbientOrNew:
                source = new CancellationTokenSource();
                token  = _cancellation.CanBeCanceled
                        ? CancellationTokenSource.CreateLinkedTokenSource(source.Token, _cancellation).Token
                        : source.Token;
                break;
            }
        }
예제 #8
0
 internal void Cancel(CancellationMode cancellationMode)
 {
     lock (this._cancellationModeLock)
     {
         if (this._cancellationMode != CancellationMode.IgnoreCancellationRequests)
         {
             this._cancellationMode = cancellationMode;
         }
         else
         {
             return;
         }
     }
     lock (this._cancelVsCloseLock)
     {
         if (this._handle != null)
         {
             MiResult miResult = OperationMethods.Cancel(this._handle, MiCancellationReason.None);
             CimException.ThrowIfMiResultFailure(miResult);
         }
     }
     this.Cancelled.SafeInvoke <EventArgs>(this, EventArgs.Empty);
 }
예제 #9
0
		internal void Cancel(CancellationMode cancellationMode)
		{
			lock (this._cancellationModeLock)
			{
				if (this._cancellationMode != CancellationMode.IgnoreCancellationRequests)
				{
					this._cancellationMode = cancellationMode;
				}
				else
				{
					return;
				}
			}
			lock (this._cancelVsCloseLock)
			{
				if (this._handle != null)
				{
					MiResult miResult = OperationMethods.Cancel(this._handle, MiCancellationReason.None);
					CimException.ThrowIfMiResultFailure(miResult);
				}
			}
			this.Cancelled.SafeInvoke<EventArgs>(this, EventArgs.Empty);
		}
예제 #10
0
        public static Task <TResult> StartWithCancellation <TResult>(Func <TResult> function, CancellationMode mode = CancellationMode.AmbientOrNew)
        {
            CancellationToken       token;
            CancellationTokenSource source;

            CreateToken(mode, out source, out token);

            Func <TResult> f = () =>
            {
                _cancellation = token;
                try
                {
                    return(function());
                }
                finally
                {
                    _cancellation = CancellationToken.None;
                }
            };

            return(Task.Factory.StartNew(f, token).AddCancellationTokenSource(source));
        }
		// ------------------------------------------------------------------
		#endregion

		#region Private methods.
		// ------------------------------------------------------------------

		/// <summary>
		/// Starts the specified worker.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="progressChanged">The progress changed.</param>
		/// <param name="runWorkerCompleted">The run worker completed.</param>
		/// <param name="text">The text.</param>
		/// <param name="use">if set to <c>true</c> [use].</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		/// <param name="owner">The owner.</param>
		private void Start(
			DoWorkEventHandler worker,
			ProgressChangedEventHandler progressChanged,
			RunWorkerCompletedEventHandler runWorkerCompleted,
			string text,
			bool use,
			CancellationMode cancellationMode,
			IWin32Window owner )
		{
			// --

			if ( use )
			{
				_progressWindow = new BackgroundWorkerLongProgressForm();
				_progressWindow.DoWork += worker;

				if ( progressChanged != null )
				{
					_progressWindow.ProgressChanged += progressChanged;
				}

				if ( runWorkerCompleted == null )
				{
					_progressWindow.RunWorkerCompleted += Default_RunWorkerCompleted;
				}
				else
				{
					_progressWindow.RunWorkerCompleted += runWorkerCompleted;
				}


				_progressWindow.IsCancelable =
					cancellationMode == CancellationMode.Cancelable;
				if ( text != null )
				{
					_progressWindow.ProgressText = text;
				}

				/*
				if ( parent is Control )
				{
				    (parent as Control).Enabled = false;
				    progressWindow.Owner = parent as Form;
				}
				*/

				if ( owner == null )
				{
					_progressWindow.ShowDialog();
				}
				else
				{
					_progressWindow.ShowDialog( owner );
				}
			}
		}
예제 #12
0
        private bool MoveNext(bool discardResultsAndErrors)
        {
            T              t              = null;
            MiResult       miResult       = MiResult.OK;
            string         str            = null;
            InstanceHandle instanceHandle = null;
            bool           flag;

            if (!discardResultsAndErrors)
            {
                lock (this._internalErrorWhileProcessingAsyncCallbackLock)
                {
                    if (this._internalErrorWhileProcessingAsyncCallback != null)
                    {
                        throw this._internalErrorWhileProcessingAsyncCallback;
                    }
                }
            }
            if (this._moreResultsAreExpected)
            {
                this.AssertNotDisposed();
                MiResult miResult1 = this.NativeMoveNext(base.Operation.Handle, out t, out this._moreResultsAreExpected, out miResult, out str, out instanceHandle);
                CimException.ThrowIfMiResultFailure(miResult1);
                if (!this._moreResultsAreExpected)
                {
                    base.Operation.IgnoreSubsequentCancellationRequests();
                }
                if (!discardResultsAndErrors)
                {
                    lock (this._internalErrorWhileProcessingAsyncCallbackLock)
                    {
                        if (this._internalErrorWhileProcessingAsyncCallback != null)
                        {
                            throw this._internalErrorWhileProcessingAsyncCallback;
                        }
                    }
                    CimException exceptionIfMiResultFailure = CimException.GetExceptionIfMiResultFailure(miResult, str, instanceHandle);
                    if (exceptionIfMiResultFailure == null)
                    {
                        this.DisposeCurrentItemIfNeeded();
                        this.Current = t;
                    }
                    else
                    {
                        CancellationMode cancellationMode = base.Operation.CancellationMode;
                        if (cancellationMode != CancellationMode.ThrowOperationCancelledException)
                        {
                            throw exceptionIfMiResultFailure;
                        }
                        else
                        {
                            throw new OperationCanceledException(exceptionIfMiResultFailure.Message, exceptionIfMiResultFailure);
                        }
                    }
                }
                else
                {
                    IDisposable disposable = (object)t as IDisposable;
                    if (disposable != null)
                    {
                        disposable.Dispose();
                        t = default(T);
                    }
                    if (instanceHandle != null)
                    {
                        instanceHandle.Dispose();
                    }
                }
                if (t == null)
                {
                    flag = this._moreResultsAreExpected;
                }
                else
                {
                    flag = true;
                }
                return(flag);
            }
            else
            {
                return(false);
            }
        }
		/// <summary>
		/// Construct with the given progress text.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="runWorkerCompleted">The run worker completed.</param>
		/// <param name="text">The text to display inside the
		/// progress form.</param>
		/// <param name="use">Indicates whether to display the progress
		/// form at all.</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		/// <param name="owner">The owner.</param>
		public BackgroundWorkerLongProgressGui(
			DoWorkEventHandler worker,
			RunWorkerCompletedEventHandler runWorkerCompleted,
			string text,
			bool use,
			CancellationMode cancellationMode,
			IWin32Window owner )
		{
			Start( worker, null, runWorkerCompleted, text, use, cancellationMode, owner );
		}
		/// <summary>
		/// Construct with the default progress text.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		public BackgroundWorkerLongProgressGui(
			DoWorkEventHandler worker,
			CancellationMode cancellationMode )
		{
			Start( worker, null, null, null, true, cancellationMode, null );
		}
예제 #15
0
        public async Task GetAsync_CancelDuringResponseHeadersReceived_TaskCanceledQuickly(bool chunkedTransfer, bool connectionClose, CancellationMode mode)
        {
            using (HttpClient client = CreateHttpClient())
            {
                client.Timeout = Timeout.InfiniteTimeSpan;
                var cts = new CancellationTokenSource();

                await LoopbackServer.CreateServerAsync(async (server, url) =>
                {
                    var partialResponseHeadersSent = new TaskCompletionSource <bool>();
                    var clientFinished             = new TaskCompletionSource <bool>();

                    Task serverTask = server.AcceptConnectionAsync(async connection =>
                    {
                        await connection.ReadRequestHeaderAndSendCustomResponseAsync(
                            $"HTTP/1.1 200 OK\r\nDate: {DateTimeOffset.UtcNow:R}\r\n"); // missing final \r\n so headers don't complete

                        partialResponseHeadersSent.TrySetResult(true);
                        await clientFinished.Task;
                    });

                    await ValidateClientCancellationAsync(async() =>
                    {
                        var req = new HttpRequestMessage(HttpMethod.Get, url);
                        req.Headers.ConnectionClose = connectionClose;

                        Task <HttpResponseMessage> getResponse = client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, cts.Token);
                        await partialResponseHeadersSent.Task;
                        Cancel(mode, client, cts);
                        await getResponse;
                    });

                    try
                    {
                        clientFinished.SetResult(true);
                        await serverTask;
                    } catch { }
                });
            }
        }
		/// <summary>
		/// Construct with the default progress text.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="progressChanged">The progress changed.</param>
		/// <param name="runWorkerCompleted">The run worker completed.</param>
		/// <param name="use">Indicates whether to display the progress
		/// form at all.</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		/// <param name="owner">The owner.</param>
		public BackgroundWorkerLongProgressGui(
			DoWorkEventHandler worker,
			ProgressChangedEventHandler progressChanged,
			RunWorkerCompletedEventHandler runWorkerCompleted,
			bool use,
			CancellationMode cancellationMode,
			IWin32Window owner )
		{
			Start( worker, progressChanged, runWorkerCompleted, null, use, cancellationMode, owner );
		}
예제 #17
0
        public async Task PostAsync_CancelDuringRequestContentSend_TaskCanceledQuickly(bool chunkedTransfer, CancellationMode mode)
        {
            if (!UseSocketsHttpHandler)
            {
                // Issue #27063: hangs / doesn't cancel
                return;
            }

            if (LoopbackServerFactory.IsHttp2 && chunkedTransfer)
            {
                // There is no chunked encoding in HTTP/2
                return;
            }

            var serverRelease = new TaskCompletionSource <bool>();
            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                try
                {
                    using (HttpClient client = CreateHttpClient())
                    {
                        client.Timeout = Timeout.InfiniteTimeSpan;
                        var cts        = new CancellationTokenSource();

                        var waitToSend     = new TaskCompletionSource <bool>();
                        var contentSending = new TaskCompletionSource <bool>();
                        var req            = new HttpRequestMessage(HttpMethod.Post, uri)
                        {
                            Version = VersionFromUseHttp2
                        };
                        req.Content = new ByteAtATimeContent(int.MaxValue, waitToSend.Task, contentSending);
                        req.Headers.TransferEncodingChunked = chunkedTransfer;

                        Task <HttpResponseMessage> resp = client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, cts.Token);
                        waitToSend.SetResult(true);
                        await contentSending.Task;
                        Cancel(mode, client, cts);
                        await ValidateClientCancellationAsync(() => resp);
                    }
                }
                finally
                {
                    serverRelease.SetResult(true);
                }
            }, async server =>
            {
                try
                {
                    await server.AcceptConnectionAsync(connection => serverRelease.Task);
                }
                catch { };  // Ignore any closing errors since we did not really process anything.
            });
        }
예제 #18
0
        public async Task PostAsync_CancelDuringRequestContentSend_TaskCanceledQuickly(bool chunkedTransfer, bool connectionClose, CancellationMode mode)
        {
            if (IsWinHttpHandler || IsNetfxHandler)
            {
                // Issue #27063: hangs / doesn't cancel
                return;
            }

            using (HttpClient client = CreateHttpClient())
            {
                client.Timeout = Timeout.InfiniteTimeSpan;
                var cts = new CancellationTokenSource();

                await LoopbackServer.CreateServerAsync(async (server, url) =>
                {
                    Task serverTask = server.AcceptConnectionAsync(async connection =>
                    {
                        // Since we won't receive all of the request, just read everything we do get
                        byte[] ignored = new byte[100];
                        while (await connection.Stream.ReadAsync(ignored, 0, ignored.Length) > 0)
                        {
                            ;
                        }
                    });

                    var preContentSent  = new TaskCompletionSource <bool>();
                    var sendPostContent = new TaskCompletionSource <bool>();

                    await ValidateClientCancellationAsync(async() =>
                    {
                        var req     = new HttpRequestMessage(HttpMethod.Post, url);
                        req.Content = new DelayedByteContent(2000, 3000, preContentSent, sendPostContent.Task);
                        req.Headers.TransferEncodingChunked = chunkedTransfer;
                        req.Headers.ConnectionClose         = connectionClose;

                        Task <HttpResponseMessage> postResponse = client.SendAsync(req, HttpCompletionOption.ResponseHeadersRead, cts.Token);
                        await preContentSent.Task;
                        Cancel(mode, client, cts);
                        await postResponse;
                    });

                    try
                    {
                        sendPostContent.SetResult(true);
                        await serverTask;
                    } catch { }
                });
            }
        }
		/// <summary>
		/// Construct with the default progress text.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="runWorkerCompleted">The run worker completed.</param>
		/// <param name="use">Indicates whether to display the progress
		/// form at all.</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		public BackgroundWorkerLongProgressGui(
			DoWorkEventHandler worker,
			RunWorkerCompletedEventHandler runWorkerCompleted,
			bool use,
			CancellationMode cancellationMode )
		{
			Start( worker, null, runWorkerCompleted, null, use, cancellationMode, null );
		}
		/// <summary>
		/// Construct with the given progress text.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="runWorkerCompleted">The run worker completed.</param>
		/// <param name="text">The text to display inside the
		/// progress form.</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		public BackgroundWorkerLongProgressGui(
			DoWorkEventHandler worker,
			RunWorkerCompletedEventHandler runWorkerCompleted,
			string text,
			CancellationMode cancellationMode )
		{
			Start( worker, null, runWorkerCompleted, text, true, cancellationMode, null );
		}
		/// <summary>
		/// Construct with the default progress text.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="progressChanged">The progress changed.</param>
		/// <param name="use">Indicates whether to display the progress
		/// form at all.</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		public BackgroundWorkerLongProgressGui(
			DoWorkEventHandler worker,
			ProgressChangedEventHandler progressChanged,
			bool use,
			CancellationMode cancellationMode )
		{
			Start( worker, progressChanged, null, null, use, cancellationMode, null );
		}
		/// <summary>
		/// Construct with the given progress text.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="progressChanged">The progress changed.</param>
		/// <param name="text">The text to display inside the
		/// progress form.</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		public BackgroundWorkerLongProgressGui(
			DoWorkEventHandler worker,
			ProgressChangedEventHandler progressChanged,
			string text,
			CancellationMode cancellationMode )
		{
			Start( worker, progressChanged, null, text, true, cancellationMode, null );
		}
		/// <summary>
		/// Construct with the given progress text.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="text">The text to display inside the
		/// progress form.</param>
		/// <param name="use">Indicates whether to display the progress
		/// form at all.</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		public BackgroundWorkerLongProgressGui(
			DoWorkEventHandler worker,
			string text,
			bool use,
			CancellationMode cancellationMode )
		{
			Start( worker, null, null, text, use, cancellationMode, null );
		}
예제 #24
0
        public async Task GetAsync_CancelDuringResponseBodyReceived_Buffered_TaskCanceledQuickly(bool chunkedTransfer, bool connectionClose, CancellationMode mode)
        {
            using (HttpClient client = CreateHttpClient())
            {
                client.Timeout = Timeout.InfiniteTimeSpan;
                var cts = new CancellationTokenSource();

                await LoopbackServer.CreateServerAsync(async (server, url) =>
                {
                    var responseHeadersSent = new TaskCompletionSource <bool>();
                    var clientFinished      = new TaskCompletionSource <bool>();

                    Task serverTask = server.AcceptConnectionAsync(async connection =>
                    {
                        await connection.ReadRequestHeaderAndSendCustomResponseAsync(
                            $"HTTP/1.1 200 OK\r\n" +
                            $"Date: {DateTimeOffset.UtcNow:R}\r\n" +
                            (!chunkedTransfer ? "Content-Length: 20\r\n" : "") +
                            (connectionClose ? "Connection: close\r\n" : "") +
                            $"\r\n123"); // "123" is part of body and could either be chunked size or part of content-length bytes, both incomplete

                        responseHeadersSent.TrySetResult(true);
                        await clientFinished.Task;
                    });

                    await ValidateClientCancellationAsync(async() =>
                    {
                        var req = new HttpRequestMessage(HttpMethod.Get, url);
                        req.Headers.ConnectionClose = connectionClose;

                        Task <HttpResponseMessage> getResponse = client.SendAsync(req, HttpCompletionOption.ResponseContentRead, cts.Token);
                        await responseHeadersSent.Task;
                        await Task.Delay(1); // make it more likely that client will have started processing response body
                        Cancel(mode, client, cts);
                        await getResponse;
                    });

                    try
                    {
                        clientFinished.SetResult(true);
                        await serverTask;
                    } catch { }
                });
            }
        }
        public async Task GetAsync_CancelPendingRequests_DoesntCancelReadAsyncOnResponseStream(CancellationMode mode, bool copyToAsync)
        {
            if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
            {
                return;
            }

            using (HttpClient client = CreateHttpClient())
            {
                client.Timeout = Timeout.InfiniteTimeSpan;

                await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
                {
                    var clientReadSomeBody = new TaskCompletionSource <bool>();
                    var clientFinished     = new TaskCompletionSource <bool>();

                    var responseContentSegment = new string('s', 3000);
                    int responseSegments       = 4;
                    int contentLength          = responseContentSegment.Length * responseSegments;

                    Task serverTask = server.AcceptConnectionAsync(async connection =>
                    {
                        await connection.ReadRequestDataAsync();
                        await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Content-Length", contentLength.ToString()) }, isFinal: false);
                        for (int i = 0; i < responseSegments; i++)
                        {
                            await connection.SendResponseBodyAsync(responseContentSegment, isFinal: i == responseSegments - 1);
                            if (i == 0)
                            {
                                await clientReadSomeBody.Task;
                            }
                        }

                        await clientFinished.Task;
                    });


                    using (HttpResponseMessage resp = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
                        using (Stream respStream = await resp.Content.ReadAsStreamAsync(TestAsync))
                        {
                            var result = new MemoryStream();
                            int b      = respStream.ReadByte();
                            Assert.NotEqual(-1, b);
                            result.WriteByte((byte)b);

                            Cancel(mode, client, null); // should not cancel the operation, as using ResponseHeadersRead
                            clientReadSomeBody.SetResult(true);

                            if (copyToAsync)
                            {
                                await respStream.CopyToAsync(result, 10, new CancellationTokenSource().Token);
                            }
                            else
                            {
                                byte[] buffer = new byte[10];
                                int bytesRead;
                                while ((bytesRead = await respStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                                {
                                    result.Write(buffer, 0, bytesRead);
                                }
                            }

                            Assert.Equal(contentLength, result.Length);
                        }

                    clientFinished.SetResult(true);
                    await serverTask;
                });
            }
        }
예제 #26
0
        public async Task GetAsync_CancelPendingRequests_DoesntCancelReadAsyncOnResponseStream(CancellationMode mode, bool copyToAsync)
        {
            if (IsNetfxHandler)
            {
                // throws ObjectDisposedException as part of Stream.CopyToAsync/ReadAsync
                return;
            }
            if (IsCurlHandler)
            {
                // Issue #27065
                // throws OperationCanceledException from Stream.CopyToAsync/ReadAsync
                return;
            }

            using (HttpClient client = CreateHttpClient())
            {
                client.Timeout = Timeout.InfiniteTimeSpan;

                await LoopbackServer.CreateServerAsync(async (server, url) =>
                {
                    var clientReadSomeBody = new TaskCompletionSource <bool>();
                    var clientFinished     = new TaskCompletionSource <bool>();

                    var responseContentSegment = new string('s', 3000);
                    int responseSegments       = 4;
                    int contentLength          = responseContentSegment.Length * responseSegments;

                    Task serverTask = server.AcceptConnectionAsync(async connection =>
                    {
                        await connection.ReadRequestHeaderAndSendCustomResponseAsync(
                            $"HTTP/1.1 200 OK\r\n" +
                            $"Date: {DateTimeOffset.UtcNow:R}\r\n" +
                            $"Content-Length: {contentLength}\r\n" +
                            $"\r\n");

                        for (int i = 0; i < responseSegments; i++)
                        {
                            await connection.Writer.WriteAsync(responseContentSegment);
                            if (i == 0)
                            {
                                await clientReadSomeBody.Task;
                            }
                        }

                        await clientFinished.Task;
                    });


                    using (HttpResponseMessage resp = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead))
                        using (Stream respStream = await resp.Content.ReadAsStreamAsync())
                        {
                            var result = new MemoryStream();
                            int b      = respStream.ReadByte();
                            Assert.NotEqual(-1, b);
                            result.WriteByte((byte)b);

                            Cancel(mode, client, null); // should not cancel the operation, as using ResponseHeadersRead
                            clientReadSomeBody.SetResult(true);

                            if (copyToAsync)
                            {
                                await respStream.CopyToAsync(result, 10, new CancellationTokenSource().Token);
                            }
                            else
                            {
                                byte[] buffer = new byte[10];
                                int bytesRead;
                                while ((bytesRead = await respStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
                                {
                                    result.Write(buffer, 0, bytesRead);
                                }
                            }

                            Assert.Equal(contentLength, result.Length);
                        }

                    clientFinished.SetResult(true);
                    await serverTask;
                });
            }
        }
예제 #27
0
		internal void IgnoreSubsequentCancellationRequests()
		{
			lock (this._cancellationModeLock)
			{
				if (this._cancellationMode == CancellationMode.NoCancellationOccured)
				{
					this._cancellationMode = CancellationMode.IgnoreCancellationRequests;
				}
			}
		}
		/// <summary>
		/// Construct with the given progress text.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="progressChanged">The progress changed.</param>
		/// <param name="runWorkerCompleted">The run worker completed.</param>
		/// <param name="text">The text to display inside the
		/// progress form.</param>
		/// <param name="use">Indicates whether to display the progress
		/// form at all.</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		public BackgroundWorkerLongProgressGui(
			DoWorkEventHandler worker,
			ProgressChangedEventHandler progressChanged,
			RunWorkerCompletedEventHandler runWorkerCompleted,
			string text,
			bool use,
			CancellationMode cancellationMode )
		{
			Start( worker, progressChanged, runWorkerCompleted, text, use, cancellationMode, null );
		}
예제 #29
0
        public bool MoveNext()
        {
            lock (_disposeThreadSafetyLock)
            {
                lock (this._internalErrorWhileProcessingAsyncCallbackLock)
                {
                    if (this._internalErrorWhileProcessingAsyncCallback != null)
                    {
                        throw this._internalErrorWhileProcessingAsyncCallback;
                    }
                }

                if (!_moreResultsAreExpected)
                {
                    return(false);
                }

                this.AssertNotDisposed();

                T           currentItem;
                MI_Result   result;
                string      errorMessage;
                MI_Instance errorDetailsHandle;
                MI_Result   functionResult = NativeMoveNext(
                    this.Operation.Handle,
                    out currentItem,
                    out this._moreResultsAreExpected,
                    out result,
                    out errorMessage,
                    out errorDetailsHandle);

                CimException.ThrowIfMiResultFailure(functionResult);
                if (!this._moreResultsAreExpected)
                {
                    this.Operation.IgnoreSubsequentCancellationRequests();
                }

                lock (this._internalErrorWhileProcessingAsyncCallbackLock)
                {
                    if (this._internalErrorWhileProcessingAsyncCallback != null)
                    {
                        throw this._internalErrorWhileProcessingAsyncCallback;
                    }
                }

                CimException cimException = CimException.GetExceptionIfMiResultFailure(result, errorMessage,
                                                                                       errorDetailsHandle);
                if (cimException != null)
                {
                    CancellationMode cancellationMode = this.Operation.CancellationMode;
                    Debug.Assert(cancellationMode != CancellationMode.SilentlyStopProducingResults,
                                 "CancellationMode.SilentlyStopProducingResults is only applicable to IObservable pattern");
                    if (cancellationMode == CancellationMode.ThrowOperationCancelledException)
                    {
                        throw new OperationCanceledException(cimException.Message, cimException);
                    }
                    else
                    {
                        throw cimException;
                    }
                }

                Debug.Assert(result == MI_Result.MI_RESULT_OK, "Exception should be thrown above in case of error");
                this.DisposeCurrentItemIfNeeded();
                this.Current = currentItem;

                bool currentResultsIsValid;
                if (currentItem != null)
                {
                    currentResultsIsValid = true;
                }
                else
                {
                    // If more results are expected, then we have to treat currentItem=null as a valid result
                    currentResultsIsValid = this._moreResultsAreExpected;

                    // Native MI API contract is that CurrentItem=null + moreResults=true should only happen 1) as the first result and 2) when CimOperationFlags.ReportOperationStarted was used.
                    // Unfortunately operation flags and knowledge whether we have first or subsequent result is not available at this point - we cannot assert the statement above :-(
                }
                return(currentResultsIsValid);
            }
        }
        public async Task GetAsync_CancelDuringResponseBodyReceived_Buffered_TaskCanceledQuickly(bool chunkedTransfer, bool connectionClose, CancellationMode mode)
        {
            if (LoopbackServerFactory.Version >= HttpVersion20.Value && (chunkedTransfer || connectionClose))
            {
                // There is no chunked encoding or connection header in HTTP/2 and later
                return;
            }

            using (HttpClient client = CreateHttpClient())
            {
                client.Timeout = Timeout.InfiniteTimeSpan;
                var cts = new CancellationTokenSource();

                await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
                {
                    var responseHeadersSent = new TaskCompletionSource <bool>();
                    var clientFinished      = new TaskCompletionSource <bool>();

                    Task serverTask = server.AcceptConnectionAsync(async connection =>
                    {
                        var headers = new List <HttpHeaderData>();
                        headers.Add(chunkedTransfer ? new HttpHeaderData("Transfer-Encoding", "chunked") : new HttpHeaderData("Content-Length", "20"));
                        if (connectionClose)
                        {
                            headers.Add(new HttpHeaderData("Connection", "close"));
                        }

                        await connection.ReadRequestDataAsync();
                        await connection.SendResponseAsync(HttpStatusCode.OK, headers: headers, content: "123", isFinal: false);
                        responseHeadersSent.TrySetResult(true);
                        await clientFinished.Task;
                    });

                    await ValidateClientCancellationAsync(async() =>
                    {
                        var req = new HttpRequestMessage(HttpMethod.Get, url)
                        {
                            Version = UseVersion
                        };
                        req.Headers.ConnectionClose = connectionClose;

                        Task <HttpResponseMessage> getResponse = client.SendAsync(TestAsync, req, HttpCompletionOption.ResponseContentRead, cts.Token);
                        await responseHeadersSent.Task;
                        await Task.Delay(1); // make it more likely that client will have started processing response body
                        Cancel(mode, client, cts);
                        await getResponse;
                    });

                    try
                    {
                        clientFinished.SetResult(true);
                        await serverTask;
                    } catch { }
                });
            }
        }
		/// <summary>
		/// Construct with the given progress text.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="text">The text to display inside the
		/// progress form.</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		/// <param name="owner">The owner.</param>
		public BackgroundWorkerLongProgressGui(
			DoWorkEventHandler worker,
			string text,
			CancellationMode cancellationMode,
			IWin32Window owner )
		{
			Start( worker, null, null, text, true, cancellationMode, owner );
		}
        public async Task PostAsync_CancelDuringRequestContentSend_TaskCanceledQuickly(bool chunkedTransfer, CancellationMode mode)
        {
            if (LoopbackServerFactory.Version >= HttpVersion20.Value && chunkedTransfer)
            {
                // There is no chunked encoding in HTTP/2 and later
                return;
            }

            if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
            {
                return;
            }

            var serverRelease = new TaskCompletionSource <bool>();
            await LoopbackServerFactory.CreateClientAndServerAsync(async uri =>
            {
                try
                {
                    using (HttpClient client = CreateHttpClient())
                    {
                        client.Timeout = Timeout.InfiniteTimeSpan;
                        var cts        = new CancellationTokenSource();

                        var waitToSend     = new TaskCompletionSource <bool>();
                        var contentSending = new TaskCompletionSource <bool>();
                        var req            = new HttpRequestMessage(HttpMethod.Post, uri)
                        {
                            Version = UseVersion
                        };
                        req.Content = new ByteAtATimeContent(int.MaxValue, waitToSend.Task, contentSending, millisecondDelayBetweenBytes: 1);
                        req.Headers.TransferEncodingChunked = chunkedTransfer;

                        Task <HttpResponseMessage> resp = client.SendAsync(TestAsync, req, HttpCompletionOption.ResponseHeadersRead, cts.Token);
                        waitToSend.SetResult(true);
                        await Task.WhenAny(contentSending.Task, resp);
                        if (!resp.IsCompleted)
                        {
                            Cancel(mode, client, cts);
                        }
                        await ValidateClientCancellationAsync(() => resp);
                    }
                }
                finally
                {
                    serverRelease.SetResult(true);
                }
            }, async server =>
            {
                try
                {
                    await server.AcceptConnectionAsync(connection => serverRelease.Task);
                }
                catch { };  // Ignore any closing errors since we did not really process anything.
            });
        }
		/// <summary>
		/// Construct with the default progress text.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="use">Indicates whether to display the progress
		/// form at all.</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		/// <param name="owner">The owner.</param>
		public BackgroundWorkerLongProgressGui(
			DoWorkEventHandler worker,
			bool use,
			CancellationMode cancellationMode,
			IWin32Window owner )
		{
			Start( worker, null, null, null, use, cancellationMode, owner );
		}
        public async Task GetAsync_CancelDuringResponseHeadersReceived_TaskCanceledQuickly(bool connectionClose, CancellationMode mode)
        {
            if (LoopbackServerFactory.Version >= HttpVersion20.Value && connectionClose)
            {
                // There is no Connection header in HTTP/2 and later
                return;
            }

            if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value)
            {
                return;
            }

            using (HttpClient client = CreateHttpClient())
            {
                client.Timeout = Timeout.InfiniteTimeSpan;
                var cts = new CancellationTokenSource();

                await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
                {
                    var partialResponseHeadersSent = new TaskCompletionSource <bool>();
                    var clientFinished             = new TaskCompletionSource <bool>();

                    Task serverTask = server.AcceptConnectionAsync(async connection =>
                    {
                        await connection.ReadRequestDataAsync();
                        await connection.SendResponseAsync(HttpStatusCode.OK, content: null, isFinal: false);

                        partialResponseHeadersSent.TrySetResult(true);
                        await clientFinished.Task;
                    });

                    await ValidateClientCancellationAsync(async() =>
                    {
                        var req = new HttpRequestMessage(HttpMethod.Get, url)
                        {
                            Version = UseVersion
                        };
                        req.Headers.ConnectionClose = connectionClose;

                        Task <HttpResponseMessage> getResponse = client.SendAsync(TestAsync, req, HttpCompletionOption.ResponseHeadersRead, cts.Token);
                        await partialResponseHeadersSent.Task;
                        Cancel(mode, client, cts);
                        await getResponse;
                    });

                    try
                    {
                        clientFinished.SetResult(true);
                        await serverTask;
                    } catch { }
                });
            }
        }
		/// <summary>
		/// Construct with the given progress text.
		/// </summary>
		/// <param name="worker">The worker.</param>
		/// <param name="progressChanged">The progress changed.</param>
		/// <param name="text">The text to display inside the
		/// progress form.</param>
		/// <param name="use">Indicates whether to display the progress
		/// form at all.</param>
		/// <param name="cancellationMode">The cancel mode.</param>
		/// <param name="owner">The owner.</param>
		public BackgroundWorkerLongProgressGui(
			DoWorkEventHandler worker,
			ProgressChangedEventHandler progressChanged,
			string text,
			bool use,
			CancellationMode cancellationMode,
			IWin32Window owner )
		{
			Start( worker, progressChanged, null, text, use, cancellationMode, owner );
		}