using System; using System.Diagnostics; using System.Threading; namespace Aliyun.Api.LOG.Common { /// /// The implementation of /// that represents the status of an async operation. /// internal abstract class AsyncResult : IAsyncResult, IDisposable { #region Fields private object _asyncState; private bool _completedSynchronously; private bool _isCompleted; private 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. /// [DebuggerNonUserCode] public object AsyncState { get { return _asyncState; } } /// /// Gets a that is used to wait for an asynchronous operation to complete. /// [DebuggerNonUserCode] public WaitHandle AsyncWaitHandle { get { if (_asyncWaitEvent != null) { return _asyncWaitEvent; } ManualResetEvent manualResetEvent = new ManualResetEvent(false); if (Interlocked.CompareExchange(ref _asyncWaitEvent, manualResetEvent, null) != null) { manualResetEvent.Close(); } if (this.IsCompleted) { _asyncWaitEvent.Set(); } return _asyncWaitEvent; } } /// /// Gets a value that indicates whether the asynchronous operation completed synchronously. /// [DebuggerNonUserCode] public bool CompletedSynchronously { get { return _completedSynchronously; } protected set { _completedSynchronously = value; } } /// /// 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) { // Complete should not throw if disposed. Debug.Assert(ex != null); _exception = ex; this.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 (!this.IsCompleted) { _asyncWaitEvent.WaitOne(); } if (this._exception != null) { throw this._exception; } } /// /// When called in the derived classes, notify operation completion /// by setting and calling the user callback. /// [DebuggerNonUserCode] protected void NotifyCompletion() { _isCompleted = true; if (_asyncWaitEvent != null) { _asyncWaitEvent.Set(); } if (_userCallback != null) { _userCallback(this); } } #region IDisposable Members /// /// Disposes the object and release resource. /// public void Dispose() { this.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. this._result = result; base.NotifyCompletion(); } } }