/* * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ using Amazon.Runtime.Internal.Util; using System; using System.Threading; namespace Amazon.Runtime.Internal { public class RuntimeAsyncResult : IAsyncResult, IDisposable { private object _lockObj; private ManualResetEvent _waitHandle; private bool _disposed = false; private bool _callbackInvoked = false; private ILogger _logger; public RuntimeAsyncResult(AsyncCallback asyncCallback, object asyncState) { _lockObj = new object(); _callbackInvoked = false; _logger = Logger.GetLogger(typeof(RuntimeAsyncResult)); this.AsyncState = asyncState; this.IsCompleted = false; this.AsyncCallback = asyncCallback; this.CompletedSynchronously = false; this._logger = Logger.GetLogger(this.GetType()); } private AsyncCallback AsyncCallback { get; set; } public object AsyncState { get; private set; } public System.Threading.WaitHandle AsyncWaitHandle { get { if (this._waitHandle != null) { return this._waitHandle; } lock (this._lockObj) { if (this._waitHandle == null) { this._waitHandle = new ManualResetEvent(this.IsCompleted); } } return this._waitHandle; } } public bool CompletedSynchronously { get; private set; } public bool IsCompleted { get; private set; } public Exception Exception { get; set; } public AmazonWebServiceResponse Response { get; set; } internal void SignalWaitHandle() { this.IsCompleted = true; if (this._waitHandle != null) { this._waitHandle.Set(); } } internal void HandleException(Exception exception) { this.Exception = exception; InvokeCallback(); } public void InvokeCallback() { this.SignalWaitHandle(); if (!_callbackInvoked) { _callbackInvoked = true; try { if(this.AsyncCallback != null) this.AsyncCallback(this); } catch (Exception e) { _logger.Error(e, "An unhandled exception occurred in the user callback."); } } } #region Dispose Pattern Implementation /// /// Implements the Dispose pattern /// /// Whether this object is being disposed via a call to Dispose /// or garbage collected. protected virtual void Dispose(bool disposing) { if (!this._disposed) { if (disposing && _waitHandle != null) { #if NETSTANDARD _waitHandle.Dispose(); #else _waitHandle.Close(); #endif _waitHandle = null; } this._disposed = true; } } /// /// Disposes of all managed and unmanaged resources. /// public void Dispose() { this.Dispose(true); GC.SuppressFinalize(this); } #endregion } }