/* * Copyright (C) Alibaba Cloud Computing * All rights reserved. * * 版权所有 (C)阿里云计算有限公司 */ using System; using System.Diagnostics; using System.Threading; using Aliyun.OSS.Common.Communication; namespace Aliyun.OSS.Util { /// /// The implementation of /// that represents the status of an async operation. /// internal abstract class AsyncResult : IAsyncResult, IDisposable { #region Fields private readonly object _asyncState; private bool _isCompleted; private readonly AsyncCallback _userCallback; private ManualResetEvent _asyncWaitEvent; private Exception _exception; #endregion #region IAsyncResult Members /// /// Gets a user-defined object that qualifies or contains information about an asynchronous operation. /// public object AsyncState { get { return _asyncState; } } public AsyncCallback Callback { get { return _userCallback; } } /// /// Gets a that is used to wait for an asynchronous operation to complete. /// public WaitHandle AsyncWaitHandle { get { if (_asyncWaitEvent != null) return _asyncWaitEvent; _asyncWaitEvent = new ManualResetEvent(false); if (IsCompleted) _asyncWaitEvent.Set(); return _asyncWaitEvent; } } /// /// Gets a value that indicates whether the asynchronous operation completed synchronously. /// public bool CompletedSynchronously { get; protected set; } /// /// Gets a value that indicates whether the asynchronous operation has completed. /// [DebuggerNonUserCode] public bool IsCompleted { get { return _isCompleted; } } #endregion /// /// Initializes an instance of . /// /// The callback method when the async operation completes. /// A user-defined object that qualifies or contains information about an asynchronous operation. protected AsyncResult(AsyncCallback callback, object state) { _userCallback = callback; _asyncState = state; } /// /// Completes the async operation with an exception. /// /// Exception from the async operation. public void Complete(Exception ex) { _exception = ex; NotifyCompletion(); } /// /// When called in the dervied classes, wait for completion. /// It throws exception if the async operation ends with an exception. /// protected void WaitForCompletion() { if (!IsCompleted) AsyncWaitHandle.WaitOne(); if (_exception != null) throw _exception; } /// /// When called in the derived classes, notify operation completion /// by setting and calling the user callback. /// protected void NotifyCompletion() { _isCompleted = true; if (_asyncWaitEvent != null) _asyncWaitEvent.Set(); if (_userCallback != null) { var httpAsyncResult = this as ServiceClientImpl.HttpAsyncResult; Debug.Assert(httpAsyncResult != null); _userCallback(httpAsyncResult.AsyncState as RetryableAsyncResult); } } #region IDisposable Members /// /// Disposes the object and release resource. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } /// /// When overrided in the derived classes, release resources. /// /// Whether the method is called protected virtual void Dispose(bool disposing) { if (disposing && _asyncWaitEvent != null) { _asyncWaitEvent.Close(); _asyncWaitEvent = null; } } #endregion } /// /// Represents the status of an async operation. /// It also holds the result of the operation. /// /// Type of the operation result. internal class AsyncResult : AsyncResult { /// /// The result of the async operation. /// private T _result; /// /// Initializes an instance of . /// /// The callback method when the async operation completes. /// A user-defined object that qualifies or contains information about an asynchronous operation. public AsyncResult(AsyncCallback callback, object state) : base(callback, state) { } /// /// Gets result and release resources. /// /// The instance of result. public T GetResult() { base.WaitForCompletion(); return _result; } /// /// Sets result and notify completion. /// /// The instance of result. public void Complete(T result) { // Complete should not throw if disposed. _result = result; base.NotifyCompletion(); } } }