Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
AsyncResult.cs254 linesDownload Raw Back to hostifaces
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Threading;5 6using Dbg = System.Management.Automation.Diagnostics;7 8namespace System.Management.Automation.Runspaces9{10    /// <summary>11    /// Base class for AsyncResult objects that are returned by various12    /// Async operations supported by RunspacePool , PowerShell types.13    /// </summary>14    internal class AsyncResult : IAsyncResult15    {16        #region Private Data17 18        private ManualResetEvent _completedWaitHandle;19        // exception occurred in the async thread.20        // user supplied state object21 22        // Invoke on thread (remote debugging support).23        private AutoResetEvent _invokeOnThreadEvent;24        private WaitCallback _invokeCallback;25        private object _invokeCallbackState;26 27        #endregion28 29        #region Constructor30 31        /// <summary>32        /// Constructor.33        /// </summary>34        /// <param name="ownerId">35        /// Instance Id of the object creating this instance36        /// </param>37        /// <param name="callback">38        /// A AsyncCallback to call once the async operation completes.39        /// </param>40        /// <param name="state">41        /// A user supplied state object42        /// </param>43        internal AsyncResult(Guid ownerId, AsyncCallback callback, object state)44        {45            Dbg.Assert(ownerId != Guid.Empty, "ownerId cannot be empty");46            OwnerId = ownerId;47            Callback = callback;48            AsyncState = state;49        }50 51        #endregion52 53        #region IAsync Overrides54 55        /// <summary>56        /// This always returns false.57        /// </summary>58        public bool CompletedSynchronously59        {60            get61            {62                return false;63            }64        }65 66        /// <summary>67        /// Gets an indication whether the asynchronous operation has completed.68        /// </summary>69        public bool IsCompleted { get; private set; }70 71        /// <summary>72        /// This is not supported and returns null.73        /// </summary>74        public object AsyncState { get; }75 76        /// <summary>77        /// Gets a System.Threading.WaitHandle that is used to wait for an asynchronous78        /// operation to complete.79        /// </summary>80        public WaitHandle AsyncWaitHandle81        {82            get83            {84                if (_completedWaitHandle == null)85                {86                    lock (SyncObject)87                    {88                        _completedWaitHandle ??= new ManualResetEvent(IsCompleted);89                    }90                }91 92                return _completedWaitHandle;93            }94        }95 96        #endregion97 98        #region properties / methods99 100        /// <summary>101        /// Instance Id of the object owning this async result.102        /// </summary>103        internal Guid OwnerId { get; }104 105        /// <summary>106        /// Gets the exception that occurred while processing the107        /// async operation.108        /// </summary>109        internal Exception Exception { get; private set; }110 111        /// <summary>112        /// User supplied callback.113        /// </summary>114        internal AsyncCallback Callback { get; }115 116        /// <summary>117        /// SyncObject.118        /// </summary>119        internal object SyncObject { get; } = new object();120 121        /// <summary>122        /// Marks the async operation as completed.123        /// </summary>124        /// <param name="exception">125        /// Exception occurred. null if no exception occurred126        /// </param>127        internal void SetAsCompleted(Exception exception)128        {129            // Dbg.Assert(!isCompleted, "AsynResult already completed");130            if (IsCompleted)131            {132                return;133            }134 135            lock (SyncObject)136            {137                if (IsCompleted)138                {139                    return;140                }141                else142                {143                    Exception = exception;144                    IsCompleted = true;145 146                    // release the threads waiting on this operation.147                    SignalWaitHandle();148                }149            }150 151            // call the user supplied callback152            Callback?.Invoke(this);153        }154 155        /// <summary>156        /// Release the asyncResult without calling the callback.157        /// </summary>158        internal void Release()159        {160            if (!IsCompleted)161            {162                IsCompleted = true;163                SignalWaitHandle();164            }165        }166 167        #endregion168 169        #region internal methods170 171        /// <summary>172        /// Signal wait handle of this async result.173        /// </summary>174        internal void SignalWaitHandle()175        {176            lock (SyncObject)177            {178                _completedWaitHandle?.Set();179            }180        }181 182        /// <summary>183        /// Wait for the operation to complete and throw the exception if any.184        /// </summary>185        internal void EndInvoke()186        {187            _invokeOnThreadEvent = new AutoResetEvent(false);188 189            // Start the thread wait loop.190            WaitHandle[] waitHandles = new WaitHandle[2] { AsyncWaitHandle, _invokeOnThreadEvent };191            bool waiting = true;192            while (waiting)193            {194                int waitIndex = WaitHandle.WaitAny(waitHandles);195 196                if (waitIndex == 0)197                {198                    waiting = false;199                }200                else201                {202                    // Invoke callback on thread.203                    try204                    {205                        _invokeCallback(_invokeCallbackState);206                    }207                    catch (Exception)208                    {209                    }210                }211            }212 213            AsyncWaitHandle.Dispose();214            _completedWaitHandle = null;  // Allow early GC215 216            _invokeOnThreadEvent.Dispose();217            _invokeOnThreadEvent = null;  // Allow early GC218 219            // Operation is done: if an exception occurred, throw it220            if (Exception != null)221            {222                throw Exception;223            }224        }225 226        /// <summary>227        /// Use blocked thread to invoke callback delegate.228        /// </summary>229        /// <param name="callback">Callback delegate.</param>230        /// <param name="state">Callback state.</param>231        internal bool InvokeCallbackOnThread(WaitCallback callback, object state)232        {233            if (callback == null)234            {235                throw new PSArgumentNullException(nameof(callback));236            }237 238            _invokeCallback = callback;239            _invokeCallbackState = state;240 241            // Signal thread to run callback.242            if (_invokeOnThreadEvent != null)243            {244                _invokeOnThreadEvent.Set();245                return true;246            }247 248            return false;249        }250 251        #endregion252    }253}254