/// <summary>
 /// Closes the <see cref="ICommunicationObject"/> if it's not in the Faulted state, but Aborts it otherwise.
 /// Additionally, if Close throws an expected exception, that exception is swallowed and the operation is Aborted.
 /// </summary>
 /// <param name="client">The <see cref="ICommunicationObject"/> on which <see cref="ICommunicationObject.Close()"/>
 /// or <see cref="ICommunicationObject.Abort()"/> will be called.</param>
 /// <remarks>For more details, see:
 /// http://msdn2.microsoft.com/en-us/library/aa355056.aspx
 /// http://msdn2.microsoft.com/en-us/library/aa354510.aspx
 /// http://bloggingabout.net/blogs/erwyn/archive/2006/12/09/WCF-Service-Proxy-Helper.aspx
 /// http://blogs.breezetraining.com.au/mickb/2006/12/19/GreatArticleOnWCF.aspx
 /// </remarks>
 public static void CloseOrAbort(this ICommunicationObject client)
 {
     if (client.State != CommunicationState.Faulted)
     {
         // client is in non-faulted state; we can attempt to Close it
         try
         {
             client.Close();
         }
         catch (CommunicationException)
         {
             client.Abort();
         }
         catch (TimeoutException)
         {
             client.Abort();
         }
         catch (Exception)
         {
             // unexpected exception--still Abort the client, but re-throw it
             client.Abort();
             throw;
         }
     }
     else
     {
         // client has already failed; have to abort
         client.Abort();
     }
 }
        /// <summary>
        /// Safely closes a service client connection.
        /// </summary>
        /// <param name="serviceClient">The service client.</param>
        public static void CloseConnection ( this ICommunicationObject serviceClient )
        {
            if ( serviceClient == null )
            {
                return;
            }

            try
            {
                if ( serviceClient.State == CommunicationState.Opened )
                {
                    serviceClient.Close ();
                }
                else
                {
                    serviceClient.Abort ();
                }
            }
            catch ( CommunicationException )
            {
                // Logging.Logger.Log(ex);
                try
                {
                    serviceClient.Abort ();
                }
                catch
                {
                } //nasty but nothing useful can be found by 
                //logging this exception as secondary issue
            }
            catch ( TimeoutException )
            {
                //Logging.Logger.Log(ex);
                try
                {
                    serviceClient.Abort ();
                }
                catch
                {
                } //nasty but nothing useful can be found by 
                //logging this exception as secondary issue
            }
            catch ( Exception )
            {
                // Logging.Logger.Log(ex);
                try
                {
                    serviceClient.Abort ();
                }
                catch
                {
                } //nasty but nothing useful can be found by 
                //logging this exception as secondary issue
                throw;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 关闭Channel
        /// </summary>
        /// <param name="channel">channel</param>
        public static void DoClose(this ICommunicationObject channel)
        {
            if (channel == null)
                return;

            switch (channel.State)
            {
                case CommunicationState.Faulted:
                    try
                    {
                        //string msg = "WCFChannelHelper:CloseChannel Faulted 调用 channel.Abort";
                        //LogHelper.WriteDebug(msg);
                        channel.Abort();
                    }
                    catch (Exception ex)
                    {
                        //LogHelper.WriteError(ex.Message, ex);
                    }
                    break;
                case CommunicationState.Closed:
                case CommunicationState.Closing:
                    break;
                default:
                    //Closing 指示通信对象正转换到 Closed 状态。 Closed 指示通信对象已关闭,且不再可用。 
                    try
                    {
                        channel.Close();

                        //string msg = "WCFChannelHelper:CloseChannel";
                        //LogHelper.WriteDebug(msg);
                    }
                    catch (CommunicationException ex)
                    {
                        //状态为 Faulted 的对象并没有关闭,可能仍在占用资源。应该使用 Abort 方法来关闭出错的对象。
                        // 如果对状态为 Faulted 的对象调用 Close,则会引发 CommunicationObjectFaultedException,这是因为没有正常关闭对象。
                        //string msg = "WCFChannelHelper.DoClose,调用channel.Abort " + ex.Message;
                        //LogHelper.WriteDebug(msg);
                        channel.Abort();
                    }
                    catch (TimeoutException ex)
                    {
                        //string msg = "WCFChannelHelper.DoClose,调用channel.Abort " + ex.Message;
                        //LogHelper.WriteDebug(msg);
                        channel.Abort();
                    }
                    catch (Exception ex)
                    {
                        //LogHelper.WriteError("DoClose:" + ex.Message, ex);
                        channel.Abort();
                    }
                    break;
            }
        }
Ejemplo n.º 4
0
 public static void CloseOrAbort(this ICommunicationObject client)
 {
     try
     {
         client.Close();
     }
     catch(CommunicationException)
     {
         client.Abort();
     }
     catch (TimeoutException)
     {
         client.Abort();
     }
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Allows GetResponseAsync call to support cancellation
        /// </summary>
        /// <param name="request"></param>
        /// <param name="ct"></param>
        /// <returns></returns>
        public static async Task<HttpWebResponse> GetResponseAsync(this HttpWebRequest request, CancellationToken ct)
        {
            using (ct.Register(() => request.Abort(), useSynchronizationContext: false))
            {
                try
                {
                    var response = await request.GetResponseAsync();
                    ct.ThrowIfCancellationRequested();
                    return (HttpWebResponse)response;
                }
                catch (WebException ex)
                {
                    // WebException is thrown when request.Abort() is called,
                    // but there may be many other reasons,
                    // propagate the WebException to the caller correctly

                    if (ct.IsCancellationRequested)
                    {
                        // the WebException will be available as Exception.InnerException
                        throw new OperationCanceledException(ex.Message, ex, ct);
                    }

                    // cancellation hasn't been requested, rethrow the original WebException
                    throw;
                }
            }
        }
 public static void Dispose(this ICommunicationObject communicationObject, TimeSpan? closeTimeout)
 {
     bool abort = true;
     try
     {
         if (closeTimeout.HasValue)
         {
             communicationObject.Close(closeTimeout.Value);
         }
         else
         {
             communicationObject.Close();
         }
         abort = false;
     }
     catch (Exception e) when (e is TimeoutException || e is CommunicationException)
     {
     }
     finally
     {
         if (abort)
         {
             Trace.TraceWarning($"{nameof(CommunicationObjectExtensionMethods)}.{nameof(Dispose)}: The communication object is being aborted.");
             communicationObject.Abort();
         }
     }
 }
        /// <summary>
        /// Tries to close the <see cref="ICommunicationObject"/>
        /// the recommended way. If this fails, an attempt is made
        /// to abort the object.
        /// </summary>
        /// <param name="communicationObject">The object to close safely.</param>
        public static void CloseSafely(this ICommunicationObject communicationObject)
        {
            if (communicationObject == null)
            {
                return;
            }

            try
            {
                communicationObject.Close();
            }
            catch (CommunicationException)
            {
                try
                {
                    communicationObject.Abort();
                }
                catch (Exception)
                {
                    try
                    {
                        // Nothing we can do here :-(
                    }
                    catch (Exception)
                    {                        
                    }
                }
            }
        }
 public static IObservable<WebResponse> GetResponseObservable(this WebRequest request)
 {
     return Observable.FromAsyncPattern(
         request.BeginGetResponse,
         result => request.EndGetResponse(result)
         )()
         .Finally(() => request.Abort());
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Aborts the thread passed. Will log information about the abortion at level 5.
 /// </summary>
 /// <param name="thread">The current instanced Thread object.</param>
 /// <returns>The current Thread.</returns>
 public static void AbortSafely(this Thread thread)
 {
     try
     {
         if (thread.ThreadState != ThreadState.Unstarted && thread.IsAlive)
             thread.Abort();
     }
     catch (ThreadAbortException) { }
 }
 /// <summary>
 /// Close or abort the ICommunicationObject depends on its state
 /// </summary>
 /// <param name="communicationObject">The communication object.</param>
 public static void CloseOrAbort(this ICommunicationObject communicationObject)
 {
     if (communicationObject.State == CommunicationState.Faulted)
     {
         communicationObject.Abort();
     }
     else
     {
         try
         {
             communicationObject.Close();
         }
         catch
         {
             communicationObject.Abort();
         }
     }
 }
Ejemplo n.º 11
0
 public static void SafeAbort(this Thread thread)
 {
     try
     {
         thread.Abort();
     }
     catch
     {
     }
 }
 /// <summary>
 /// Safely closes the communication channel, aborting the channel if any exceptions are raised during the close
 /// </summary>
 /// <param name="channel"></param>
 public static void CloseSafely(this ICommunicationObject channel)
 {
     try
     {
         if (channel.State != CommunicationState.Faulted)
         {
             channel.Close();
         }
         else
         {
             channel.Abort();
         }
     }
     catch (Exception ex)
     {
         Log.Trace("{0} - exception raised in CloseSafely", channel.GetType().FullName);
         channel.Abort();
     }
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Aborts a thread and catches all the exceptions if some occurs.
 /// </summary>
 /// <param name="thread">The thread to abort.</param>
 /// <returns>If an exception occured.</returns>
 internal static bool AbortSave(this Thread thread)
 {
     try
     {
         thread.Abort();
         return false;
     }
     catch
     {
         return true;
     }
 }
Ejemplo n.º 14
0
        public static bool TryKill(this Thread thread)
        {
            try
            {
                thread.Abort();

                return true;
            }
            catch
            {
                return false;
            }
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Close the remoting connection for the current WCF proxy instance without exception safely.
        /// 安全的为WCF调用代理对象关闭远程连接
        /// </summary>
        /// <param name="proxy"></param>
        /// <example>
        /// try
        /// {
        ///     proxy.Method();
        /// }
        /// catch(Exception ex)
        /// {
        ///     // Handle the exception
        /// }
        /// finally
        /// {
        ///     proxy.CloseConnection();
        /// }
        /// </example>
        public static void CloseConnection(this System.ServiceModel.ICommunicationObject proxy)
        {
            if (proxy.State != System.ServiceModel.CommunicationState.Opened) { return; }

            try
            {
                proxy.Close();
            }
            catch (System.ServiceModel.CommunicationException)
            {
                proxy.Abort();
            }
            catch (TimeoutException)
            {
                proxy.Abort();
            }
            catch (Exception)
            {
                proxy.Abort();
                throw;
            }
        }
Ejemplo n.º 16
0
 ///<summary>
 ///</summary>
 ///<param name="obj"></param>
 public static void CloseSafely(this ICommunicationObject obj)
 {
     if (obj != null)
     {
         if (obj.State != CommunicationState.Faulted &&
             obj.State != CommunicationState.Closed)
         {
             try { obj.Close(); }
             catch (CommunicationObjectFaultedException)
             { obj.Abort(); }
             catch (TimeoutException)
             { obj.Abort(); }
             catch (Exception)
             {
                 obj.Abort();
                 throw;
             }
         }
         else
             obj.Abort();
     }
 }
 public static void Dispose(this CommunicationObject communicationObject)
 {
     if (communicationObject == null)
     {
         return;
     }
     if (CommunicationState.Opened.Equals(communicationObject.State))
     {
         communicationObject.Close();
     }
     else
     {
         communicationObject.Abort();
     }
 }
	    public static async Task<IObservable<string>> ServerPullAsync(this HttpWebRequest webRequest, int retries = 0)
	    {
#if SILVERLIGHT
            webRequest.AllowReadStreamBuffering = false;
			webRequest.AllowWriteStreamBuffering = false;
#endif
		    var task = await webRequest.GetResponseAsync();

		    var stream = task.GetResponseStreamWithHttpDecompression();
		    var observableLineStream = new ObservableLineStream(stream, () =>
			    {
				    webRequest.Abort();
				    task.Close();
			    });
		    observableLineStream.Start();
		    return (IObservable<string>) observableLineStream;
	    }
Ejemplo n.º 19
0
        /// <summary>
        ///   Abort a thread if it doesn't join n milliseconds after an interrupt.
        /// </summary>
        /// <param name="thread"> </param>
        /// <param name="millisecondsTimeout"> </param>
        public static void Kill(this Thread thread, int millisecondsTimeout = 0)
        {
            try
            {
                thread.Interrupt();
                if (thread.Join(millisecondsTimeout)) return;
            }
            catch (ThreadInterruptedException)
            {
            }

            try
            {
                thread.Abort();
            }
            catch (ThreadAbortException)
            {
            }
            catch (ThreadInterruptedException)
            {
            }
        }
Ejemplo n.º 20
0
        public static async Task<WebResponse> GetResponseAsync(this WebRequest request,
            CancellationToken ct)
        {
            using (ct.Register(() => request.Abort(), useSynchronizationContext: false))
            {
                try
                {
                    var response = await request.GetResponseAsync();
                    ct.ThrowIfCancellationRequested();
                    return (WebResponse)response;
                }
                catch (WebException e)
                {
                    if (e.Status == WebExceptionStatus.RequestCanceled)
                        ct.ThrowIfCancellationRequested();

                    if (ct.IsCancellationRequested)
                        throw new TaskCanceledException(e.Message, e);

                    throw;
                }
            }
        }
        /// <summary>
        /// A blocking operation that does not continue until a response has been
        /// received for a given <see cref="HttpWebRequest"/>, or the request
        /// timed out.
        /// </summary>
        /// <param name="request">The request to be sent.</param>
        /// <param name="timeout">An optional timeout.</param>
        /// <returns>The response that was received for the request.</returns>
        /// <exception cref="TimeoutException">If the <paramref name="timeout"/>
        /// parameter was set, and no response was received within the specified
        /// time.</exception>
        /// <see href="http://www.hardcodet.net/2010/02/blocking-httpwebrequest-getresponse-for-silverlight"/>
        public static HttpWebResponse GetSyncResponse(this HttpWebRequest request,
                                                  int? timeout)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            /*
             * TODO:
             * Check if this method is usable when called from the UI thread in Silverlight
             * if not, see how we could throw an exception when this is the case (otherwise it just hangs)
             */
            var waitHandle = new AutoResetEvent(false);
            HttpWebResponse response = null;
            Exception exception = null;

            AsyncCallback callback = ar =>
            {
                try
                {
                    //get the response
                    response = (HttpWebResponse) request.EndGetResponse(ar);
                }
                catch (WebException we)
                {
                    if (we.Status != WebExceptionStatus.RequestCanceled)
                    {
                        exception = we;
                    }
                }
                catch (Exception e)
                {
                    exception = e;
                }
                finally
                {
                    //setting the handle unblocks the loop below
                    waitHandle.Set();
                }
            };

            //request response async
            var asyncResult = request.BeginGetResponse(callback, null);
            if (asyncResult.CompletedSynchronously) return response;

            var hasSignal = waitHandle.WaitOne(timeout ?? Timeout.Infinite);
            if (!hasSignal)
            {
                try
                {
                    if (response != null)
                        return response;
                    if (request != null)
                        request.Abort();
                }
                catch
                {
                    //throw new TimeoutException("No response received in time.");
                }

                //throw new TimeoutException("No response received in time.");
            }

            //bubble exception that occurred on worker thread
            if (exception != null) throw exception;

            return response;
        }
        /// <summary>
        /// Returns a response to an Internet request as an asynchronous operation.
        /// </summary>
        /// <remarks>
        /// <para>This operation will not block. The returned <see cref="Task{TResult}"/> object will
        /// complete after a response to an Internet request is available.</para>
        /// </remarks>
        /// <param name="request">The request.</param>
        /// <param name="throwOnError"><see langword="true"/> to throw a <see cref="WebException"/> if the <see cref="HttpWebResponse.StatusCode"/> of the response is greater than 400; otherwise, <see langword="false"/> to return the <see cref="WebResponse"/> in the result for these cases.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new <see cref="Task"/>.</param>
        /// <returns>A <see cref="Task"/> object which represents the asynchronous operation.</returns>
        /// <exception cref="ArgumentNullException">
        /// <para>If <paramref name="request"/> is <see langword="null"/>.</para>
        /// </exception>
        /// <exception cref="WebException">
        /// <para>If <see cref="WebRequest.Abort"/> was previously called.</para>
        /// <para>-or-</para>
        /// <para>If the timeout period for the request expired.</para>
        /// <para>-or-</para>
        /// <para>If an error occurred while processing the request.</para>
        /// </exception>
        public static Task<WebResponse> GetResponseAsync(this WebRequest request, bool throwOnError, CancellationToken cancellationToken)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            #if PORTABLE
            bool timeout = false;

            CancellationTokenRegistration cancellationTokenRegistration;
            if (cancellationToken.CanBeCanceled)
            {
                Action cancellationAction = request.Abort;
                cancellationTokenRegistration = cancellationToken.Register(cancellationAction);
            }
            else
            {
                cancellationTokenRegistration = default(CancellationTokenRegistration);
            }

            CancellationTokenSource noRequestTimeoutTokenSource = new CancellationTokenSource();
            WebExceptionStatus timeoutStatus;
            if (!Enum.TryParse("Timeout", out timeoutStatus))
                timeoutStatus = WebExceptionStatus.UnknownError;

            int requestTimeout;
            #if NET45PLUS
            try
            {
                // hack to work around PCL limitation in .NET 4.5
                dynamic dynamicRequest = request;
                requestTimeout = dynamicRequest.Timeout;
            }
            catch (RuntimeBinderException)
            {
                requestTimeout = Timeout.Infinite;
            }
            #else
            // hack to work around PCL limitation in .NET 4.0
            var propertyInfo = request.GetType().GetProperty("Timeout", typeof(int));
            if (propertyInfo != null)
            {
                requestTimeout = (int)propertyInfo.GetValue(request, null);
            }
            else
            {
                requestTimeout = Timeout.Infinite;
            }
            #endif

            if (requestTimeout >= 0)
            {
                Task timeoutTask = DelayedTask.Delay(TimeSpan.FromMilliseconds(requestTimeout), noRequestTimeoutTokenSource.Token).Select(
                    _ =>
                    {
                        timeout = true;
                        request.Abort();
                    });
            }

            TaskCompletionSource<WebResponse> completionSource = new TaskCompletionSource<WebResponse>();

            AsyncCallback completedCallback =
                result =>
                {
                    try
                    {
                        noRequestTimeoutTokenSource.Cancel();
                        noRequestTimeoutTokenSource.Dispose();
                        cancellationTokenRegistration.Dispose();
                        completionSource.TrySetResult(request.EndGetResponse(result));
                    }
                    catch (WebException ex)
                    {
                        if (timeout)
                            completionSource.TrySetException(new WebException("No response was received during the time-out period for a request.", timeoutStatus));
                        else if (cancellationToken.IsCancellationRequested)
                            completionSource.TrySetCanceled();
                        else if (ex.Response != null && !throwOnError)
                            completionSource.TrySetResult(ex.Response);
                        else
                            completionSource.TrySetException(ex);
                    }
                    catch (Exception ex)
                    {
                        completionSource.TrySetException(ex);
                    }
                };

            IAsyncResult asyncResult = request.BeginGetResponse(completedCallback, null);
            return completionSource.Task;
            #else
            bool timeout = false;
            TaskCompletionSource<WebResponse> completionSource = new TaskCompletionSource<WebResponse>();

            RegisteredWaitHandle timerRegisteredWaitHandle = null;
            RegisteredWaitHandle cancellationRegisteredWaitHandle = null;
            AsyncCallback completedCallback =
                result =>
                {
                    try
                    {
                        if (cancellationRegisteredWaitHandle != null)
                            cancellationRegisteredWaitHandle.Unregister(null);

                        if (timerRegisteredWaitHandle != null)
                            timerRegisteredWaitHandle.Unregister(null);

                        completionSource.TrySetResult(request.EndGetResponse(result));
                    }
                    catch (WebException ex)
                    {
                        if (timeout)
                            completionSource.TrySetException(new WebException("No response was received during the time-out period for a request.", WebExceptionStatus.Timeout));
                        else if (cancellationToken.IsCancellationRequested)
                            completionSource.TrySetCanceled();
                        else if (ex.Response != null && !throwOnError)
                            completionSource.TrySetResult(ex.Response);
                        else
                            completionSource.TrySetException(ex);
                    }
                    catch (Exception ex)
                    {
                        completionSource.TrySetException(ex);
                    }
                };

            IAsyncResult asyncResult = request.BeginGetResponse(completedCallback, null);
            if (!asyncResult.IsCompleted)
            {
                if (request.Timeout != Timeout.Infinite)
                {
                    WaitOrTimerCallback timedOutCallback =
                        (object state, bool timedOut) =>
                        {
                            if (timedOut)
                            {
                                timeout = true;
                                request.Abort();
                            }
                        };

                    timerRegisteredWaitHandle = ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, timedOutCallback, null, request.Timeout, true);
                }

                if (cancellationToken.CanBeCanceled)
                {
                    WaitOrTimerCallback cancelledCallback =
                        (object state, bool timedOut) =>
                        {
                            if (cancellationToken.IsCancellationRequested)
                                request.Abort();
                        };

                    cancellationRegisteredWaitHandle = ThreadPool.RegisterWaitForSingleObject(cancellationToken.WaitHandle, cancelledCallback, null, Timeout.Infinite, true);
                }
            }

            return completionSource.Task;
            #endif
        }
Ejemplo n.º 23
0
 public static void KuduAbort(this Thread thread, string message)
 {
     thread.Abort(String.Format("{0}  {1}", KuduThreadAbortMessage, message));
 }
        /// <summary>
        /// Returns a response to an Internet request as an asynchronous operation.
        /// </summary>
        /// <remarks>
        /// This operation will not block. The returned <see cref="Task{TResult}"/> object will
        /// complete after a response to an Internet request is available.
        /// </remarks>
        /// <param name="request">The request.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/> that will be assigned to the new <see cref="Task"/>.</param>
        /// <returns>A <see cref="Task"/> object which represents the asynchronous operation.</returns>
        /// <exception cref="ArgumentNullException">If <paramref name="request"/> is <see langword="null"/>.</exception>
        /// <exception cref="WebException">
        /// If <see cref="WebRequest.Abort"/> was previously called.
        /// <para>-or-</para>
        /// <para>If the timeout period for the request expired.</para>
        /// <para>-or-</para>
        /// <para>If an error occurred while processing the request.</para>
        /// </exception>
        public static Task<WebResponse> GetResponseAsync(this WebRequest request, CancellationToken cancellationToken)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            bool timeout = false;
            TaskCompletionSource<WebResponse> completionSource = new TaskCompletionSource<WebResponse>();

            RegisteredWaitHandle timerRegisteredWaitHandle = null;
            RegisteredWaitHandle cancellationRegisteredWaitHandle = null;
            AsyncCallback completedCallback =
                result =>
                {
                    try
                    {
                        if (cancellationRegisteredWaitHandle != null)
                            cancellationRegisteredWaitHandle.Unregister(null);

                        if (timerRegisteredWaitHandle != null)
                            timerRegisteredWaitHandle.Unregister(null);

                        completionSource.TrySetResult(request.EndGetResponse(result));
                    }
                    catch (WebException ex)
                    {
                        if (timeout)
                            completionSource.TrySetException(new WebException("No response was received during the time-out period for a request.", WebExceptionStatus.Timeout));
                        else if (cancellationToken.IsCancellationRequested)
                            completionSource.TrySetCanceled();
                        else
                            completionSource.TrySetException(ex);
                    }
                    catch (Exception ex)
                    {
                        completionSource.TrySetException(ex);
                    }
                };

            IAsyncResult asyncResult = request.BeginGetResponse(completedCallback, null);
            if (!asyncResult.IsCompleted)
            {
                if (request.Timeout != Timeout.Infinite)
                {
                    WaitOrTimerCallback timedOutCallback =
                        (object state, bool timedOut) =>
                        {
                            if (timedOut)
                            {
                                timeout = true;
                                request.Abort();
                            }
                        };

                    timerRegisteredWaitHandle = ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, timedOutCallback, null, request.Timeout, true);
                }

                if (cancellationToken.CanBeCanceled)
                {
                    WaitOrTimerCallback cancelledCallback =
                        (object state, bool timedOut) =>
                        {
                            if (cancellationToken.IsCancellationRequested)
                                request.Abort();
                        };

                    cancellationRegisteredWaitHandle = ThreadPool.RegisterWaitForSingleObject(cancellationToken.WaitHandle, cancelledCallback, null, Timeout.Infinite, true);
                }
            }

            return completionSource.Task;
        }