diff --git a/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs b/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs index 3d4d6fb14de..ad577a49673 100644 --- a/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs +++ b/src/Mono.Android/Xamarin.Android.Net/AndroidClientHandler.cs @@ -209,8 +209,8 @@ string EncodeUrl (Uri url) while (true) { URL java_url = new URL (EncodeUrl (redirectState.NewUrl)); URLConnection java_connection = java_url.OpenConnection (); - HttpURLConnection httpConnection = await SetupRequestInternal (request, java_connection); - HttpResponseMessage response = await ProcessRequest (request, java_url, httpConnection, cancellationToken, redirectState); + HttpURLConnection httpConnection = await SetupRequestInternal (request, java_connection).ConfigureAwait (continueOnCapturedContext: false);; + HttpResponseMessage response = await ProcessRequest (request, java_url, httpConnection, cancellationToken, redirectState).ConfigureAwait (continueOnCapturedContext: false);; if (response != null) return response; @@ -235,6 +235,19 @@ Task DisconnectAsync (HttpURLConnection httpConnection) return Task.Run (() => httpConnection?.Disconnect ()); } + Task ConnectAsync (HttpURLConnection httpConnection, CancellationToken ct) + { + return Task.Run (() => { + try { + using (ct.Register (() => httpConnection?.Disconnect ())) + httpConnection?.Connect (); + } catch { + ct.ThrowIfCancellationRequested (); + throw; + } + }, ct); + } + async Task DoProcessRequest (HttpRequestMessage request, URL javaUrl, HttpURLConnection httpConnection, CancellationToken cancellationToken, RequestRedirectionState redirectState) { if (Logger.LogNet) @@ -247,20 +260,11 @@ Task DisconnectAsync (HttpURLConnection httpConnection) cancellationToken.ThrowIfCancellationRequested (); } - CancellationTokenSource waitHandleSource = new CancellationTokenSource(); try { if (Logger.LogNet) Logger.Log (LogLevel.Info, LOG_APP, $" connecting"); - CancellationToken linkedToken = CancellationTokenSource.CreateLinkedTokenSource(waitHandleSource.Token, cancellationToken).Token; - await Task.WhenAny ( - httpConnection.ConnectAsync (), - Task.Run (()=> { - linkedToken.WaitHandle.WaitOne(); - if (Logger.LogNet) - Logger.Log(LogLevel.Info, LOG_APP, $"Wait handle task finished"); - })) - .ConfigureAwait(false); + await ConnectAsync (httpConnection, cancellationToken).ConfigureAwait (continueOnCapturedContext: false); if (Logger.LogNet) Logger.Log (LogLevel.Info, LOG_APP, $" connected"); } catch (Java.Net.ConnectException ex) { @@ -268,9 +272,6 @@ await Task.WhenAny ( Logger.Log (LogLevel.Info, LOG_APP, $"Connection exception {ex}"); // Wrap it nicely in a "standard" exception so that it's compatible with HttpClientHandler throw new WebException (ex.Message, ex, WebExceptionStatus.ConnectFailure, null); - } finally{ - //If not already cancelled, cancel the WaitOne through the waitHandleSource to prevent an orphaned thread - waitHandleSource.Cancel(); } if (cancellationToken.IsCancellationRequested) { @@ -541,7 +542,7 @@ void CopyHeaders (HttpURLConnection httpConnection, HttpResponseMessage response /// Pre-configured connection instance protected virtual Task SetupRequest (HttpRequestMessage request, HttpURLConnection conn) { - return Task.Factory.StartNew (AssertSelf); + return Task.Run (AssertSelf); } /// @@ -645,9 +646,9 @@ void AppendEncoding (string encoding, ref List list) } HandlePreAuthentication (httpConnection); - await SetupRequest (request, httpConnection); + await SetupRequest (request, httpConnection).ConfigureAwait (continueOnCapturedContext: false);; SetupRequestBody (httpConnection, request); - + return httpConnection; }